DaedTech

Stories about Software

By

Chess TDD 11: Tying Up Loose Ends

Now that all of the pieces are implemented, I decided to change it up a little and get rid of a few yellow items in one fell swoop. I thought it would also be a good time to
Here’s what I accomplish in this clip:

  • Move Knight into it’s own class.
  • Separated test and production into their own assemblies.
  • Got rid of the DefaultBoardSize constant that had been defined in many test classes by consolidating it into one place.
  • Went back to earlier test classes and implemented “MovesFromXX” pattern that I had settled on.

Here are some lessons to take away:

  • If Ctrl-M, O stops working (or any normal VS shortcut), it might be because some other process has claimed part or all of the sequence and is preempting Studio.  Kill processes or reboot.
  • If you have some mundane but necessary tasks (e.g. moving a bunch of classes into a new namespace), this can be a good way to “warm up” when you haven’t looked at a code base in a while.  Generally speaking, look for tasks that can ease you back into the code base while being productive.
  • Even duplication that is seemingly mundane should be avoided.  The DRY principle states that systems should have a single point of definition for all pieces of knowledge, and that includes things like database schemas, config files, and yes, even your unit test classes.  You need to maintain your unit tests, and duplication creates maintenance pain.
  • Pay attention to your test method names as you’re making changes.  These are documentation as to how your code should behave, so if you change the behavior, make sure to change the names to reflect those changes.
  • “Lean on the compiler” to help you with your refactorings.  If you’re getting rid of a bunch of references to a variable, delete the definition of the variable and the compiler will then force you to get rid of all references.  If you do it in the opposite order, you might miss references and waste time.  As a more general rule, you should always favor failing early and doing things in such a way that mistakes will result in non-compiling.
  • When you do large refactorings, it might not hurt to run all of the unit tests explicitly in the test runner instead of relying on the dots in NCrunch (or any continuous testing tool that you’re using).

By

Chess TDD 10: A Knight’s Tale

Okay, I promise, no more of these titles after this edition.  But, to make up for it, this time I actually wrote the code and did the audio in the same day, so I remember very well what I was talking about.

Here’s what I accomplish in this clip:

  • Move Queen into it’s own class.
  • Implement Knight with GetMovesFrom()

Here are some lessons to take away:

  • It’s okay to be obtuse for a while in your TDD, if doing so helps your understanding. I started with a hard-coded thing to get the first test pass and then did another for the second. Both tests would need to continue passing, and I was feeling my way through what to do. As long as you get going at some point, this is okay. Whatever helps.
  • Try to avoid getting into a routine. By getting a fresh look, I was able to define a method that I thought improved readability and aided code use. I’d written a number of things like this before, but I always try to think of new ways to approach problems, rather than settling into a routine of semi-mindless work.
  • If you’re not careful, you can get a little ahead of yourself. I was on auto-pilot and didn’t realize I wasn’t compiling for a while before I corrected myself.
  • Get it working first, and then worry about cleanup later. You can always make things more elegant later, when it’s working (at least when you do TDD).

By

TDD Chess Game Part 9: God Save the Queen

As always, it seems that I’ve let too much time elapse between iterations of this series. This time my excuse was worse than ever. I actually had this video ready to go last Friday or something and then the post was was queued up on Sunday, but I was too tired when I got home on Sunday night to remember to go publish it. Anyway, it’s live now.

Here’s what I accomplish in this clip:

  • Implement Queen with GetMovesFrom()
  • Add more common functionality to Piece base class.

Here are some lessons to take away:

  • For the most part, in the last number of clips things had gone more or less as I expected.  Here you got to see the value of the test suite indicating to me that I was reasoning about the code incorrectly.  I didn’t realize that the GetRadial methods were returning only moves N spaces away rather than up to and including N spaces.  It took some floundering to figure this out and, without red tests telling me things were going haywire, I probably would have plowed ahead for minutes or hours before I realized things weren’t working.
  • Pulling up functionality into a common base class is a way to avoid duplication and make tests go green rapidly, but beware of creating a base class abstraction that’s awkward just to reuse code.  If it seems awkward, it might be worth creating a class that your ancestors use.  So far, the functionality in Piece seems to make sense, but I’ll keep an eye on this.
  • Use Intellisense in a savvy way.  When you notice a few times that what you’re expecting to happen isn’t happening, that’s a yellow (if not red) flag.  Late in the video, this kept happening to me, and it turned out to be because I had spelled “radial” as “raidal” when defining a method.  Typos, incorrect assumptions, etc — often these things can be revealed by the IDE not behaving as expected.
  • Definitely keep track of refactorings you’d like to do in you list.  Treat these as if they were no different than features you want implemented.

By

TDD Chess Game Part 8: Hail to the King

Today’s episode is one with a pretty directed focus. I’m actually typing this prior to doing the screen capture, but I know what I want to do ahead of time. I want to implement the King piece, and I have a relatively good idea how to do it.

Here’s what I accomplish in this clip:

  • Implement King with GetMovesFrom()

Here are some lessons to take away:

  • Sometimes you’ll go into a coding session with a discrete, obvious goal, and other times you’ll have to break a nebulous goal into discrete, obvious ones.  But you always want discrete, obvious ones if you can.
  • If you can save yourself using the mouse via being proficient with keyboard shortcuts, I’d definitely go this route.  The time savings amortize over lots of coding.
  • For “simplest thing” in TDD, it doesn’t always mean that you have to bang out a line of code.  Maybe you can pull an existing method to a common ancestor and use it, or instantiate and use some other object.
  • “Simplest thing” is kind of an art form geared toward your best productivity.  If you’re new to the process of TDD, you probably want to keep it really simple before you’re experienced enough to be discerning.  Once you’ve established it and gotten good at the basics, you can adjust to situational taste.  Perhaps sometimes you’re stuck and need to get really simple while, in other cases, you have a good grasp on what comes next and being obtuse would just be busy-word.  Practice and use your judgment.
  • If you’re using a continuous testing tool (and specifically C#), pay attention to coverage with IEnumerables.  It seems trivial, but it’s really better if you’re executing every line, even if it just means calling ToList() somewhere.

By

Starting to Unit Test: Not as Hard as You’d Think

I happened to read a post by Dror Helper the other day, in which he said:

I believe TDD and “unit tests” has been done a great injustice by not giving it a cooler name – preferable one that doesn’t have the word “test” in it – because it’s a PR disaster!

Wow, that had never occurred to me, and yet he’s spot on. “Unit test” is a wretched name for anything. It seems somehow to combine all the worst elements of propagating uncertainty in arithmetic with lab measurements and double checking all of your answers on a scantron exam. I just bored myself half to death typing that sentence, so it’s little wonder that the concept of a “unit test” is often met with a visceral “ugh.” I mean, we could at the least call the test suite a “verification checklist” or something, implying that you’re marking progress as you complete things. It’s not exactly a skydiving trip, but it has to beat “unit test.” But I digress.

The lack of appeal of the name, the feeling of already being pressed for time without taking something else on, and the natural resistance to the unknown all create barriers to entry when it comes to unit testing. In order to get started yourself, or especially to convince those around you to do the same, it’s necessary to overcome those barriers. I have a good bit of experience with this in a variety of environments and from a variety of roles. Over the last year, I did a string of blog posts that were essentially my talking scripts for a series of power point/demo talks I gave. These were meant to be an introduction to unit testing.

The series actually became pretty long, and as I was finishing it, I decided to put it into E-Book format. So, with the help of my editor, we turned it into fluid book, and with the help my publisher, we published it in all major E-Book formats for a cost of $4.99. Here is the book on the publisher’s site, and here is a link directly to Amazon
for Kindle readers (full disclosure: I’m experimenting with affiliate links, and that’s why I’m specifically linking Amazon directly).

The title of the book is “Starting to Unit Test: Not as Hard as You Think,” and I feel that the title really captures it. My goal was to trade practice purity for reducing the barriers to entry. In other words, the message was, “don’t feel like you have to start full bore with 100% coverage, TDD, and anything less is a failure — if you just introduce a few tests into a few places in your code, consider that a win.” I also did something else that I haven’t seen others do as much, which is to explain that some types of frameworks and code present unit testing nightmares, and that newbie unit testers should avoid them until they reach a higher belt.” What I’d like to see people take away from this book is a feeling of satisfaction from experiencing a sequence of small but real wins.

For you mythology buffs, this is Sysiphus actually making it to the top of the hill.

For you mythology buffs, this is Sysiphus actually making it to the top of the hill.

By and large, you could get this content by reading through my blog posts on the subject, but if you want it in a compact format, here it is. Not to mention, if you’re trying to sell your team on the merits of unit testing, a book is probably going to have more cachet than a series of blog posts, and the one link to the book is going to be easier to distribute than the giant collection of links for the individual posts/chapters. So get it if you’re interested, and encourage your team to get it if you’re trying to introduce the concept, especially since I close out the book by making a business case for unit testing (this making cases for best practices is actually going to be a theme of mine in the future).

Enjoy, and thanks for reading (the blog and, hopefully, the book)!