DaedTech

Stories about Software

By

Chess TDD 55: Got the Hang of Castling

In this episode, it seems I finally got the hang of castling.  It’s been a relatively long journey with it, but I can now successfully detect castling situations that involve any combination of rook/king prior movement, as well as interceding pieces.  The only thing left to go is the relative edge case of a castling through check scenario, but I’ll consider that to be part of the implementation of the check concept.

What I accomplish in this clip:

  • Re-hydrated the acceptance test that I’d left off with last time and got it passing.
  • Refactored toward a less naive implementation of blocking, and then got it passing for all cases on both sides.

Here are some lessons to take away:

  • If you’ve written a failing acceptance test and are struggling to see how to get it to pass, see if you can express the same scenario with a more granular unit test.  This can focus you and help prevent your brain from spinning.
  • If you have the feeling that you’ve implemented something before (or a teammate has), it is definitely worth pausing to investigate.  You don’t want oddball solutions to the same problem, which can be as damaging as copy and paste programming.
  • You’ll never get away from making mistakes of all sorts.  Take note how in this episode, I probably got a bit too ambitious with solving the whole problem at once, which led to a lot of staring at the screen.  I probably should have made use of more failing tests to get there more gradually.
  • When you feel that you have coder’s block and aren’t sure what to do next, that’s the best time to implement something naive and ugly.  There’s no need to be afraid, since you’ll refactor shortly, but just getting anything out there can un-stick you.

By

The Wrong Thing more Efficiently is Still the Wrong Thing

Editorial Note: I originally wrote this post for the Infragistics blog.  Go check out the original post on their site and take a look around while you’re there to see some of the other authors posting interesting things.

Let’s say that, like many folks, one of your first tasks each morning is dealing with your email. You arrive at the office, grab yourself a coffee, and settle in to complete this ubiquitous modern task.

Naturally, the first thing you do is open your inbox. Then you open each unread email, select all, and copy it. Next, you open a new instance of Visual Studio, create a console project, add a text file to it, and paste the email text into that text file. By the end of doing this, you have somewhere between 2 and 20 instances of Visual Studio running, depending on how many unread emails you have. At this point, you’re ready to read the emails, so you alt-tab among the VS instances, closing each one after you’ve read the email.

This system works well for you, but there are two major drawbacks. First of all, it’s a real hassle to have to create a new project and a text file manually, and then open the text file. It’d be awesome if there were a way that you could make Visual Studio do this for you. And secondly, all of those instances of Visual Studio have a tendency to cause your machine to thrash, and they sometimes just crash.

ScaryComputer

What to do? I’ll come back to that.

Read More

By

Chess TDD 54: Castling Acceptance Tests

The last few episodes featured heads down implementation around this new CastlingStatusChecker class.  It was nice to spend some time writing relatively simple unit tests to restore some sanity and get away from an overly-coupled Board class.  But, it was time to come up for some air and get back to proving some business/domain value.  Toward that end, I found myself writing castling acceptance tests.  But, before I could start with that, I cleaned up the constants that had grown a little awkward after my re-imagined implementations of the status checker.  All sorted out now, though.

What I accomplish in this clip:

  • Refactored constants in the castling status checker and the test class I was using to drive its implementation.
  • Starting on the castling acceptance tests, which worked for black and white pieces.

Here are some lessons to take away:

  • There’s no exact science to climbing up and down the granularity levels.  The heuristic I offer in this episode is, essentially, “prefer unit tests because there’s less setup and faster feedback, but come up for air periodically and use acceptance tests to verify that you’re adding business value.”
  • Make your code read plainly, like prose, in production.  When it comes to writing unit tests, go even an extra step, and act as if you were writing a Word document about your code (maybe not literally, but you get the idea).  The unit tests are where you explain how the system works.
  • It’s perfectly reasonable to write a series of acceptance tests that you expect to go green.  These acceptance tests are how you document and prove functionality to non-technical stakeholders if they have an appetite for reading and collaborating on them.  So, by all means, take the time to demo the app’s behavior by writing as many of these as you need to showcase what it’s doing.

By

Chess TDD 53: Castling for Black Pieces

After a couple  of episodes working on castling for white, and then an episode refactoring that implementation, it’s finally time to implement castling for black pieces.  This actually went pretty well.  The groundwork that I had laid in the previous episodes made life a lot easier for me here.  It wasn’t perfect, by the end, but it’s getting encouragingly close to “good enough to move on.”  With castling and en passant both soon to be in hand, it may be time to move to clean up mode with more elaborate acceptance scenarios.  A light at the end of the tunnel?

What I accomplish in this clip:

  • Finished basic implementation of castling checker.

Here are some lessons to take away:

  • It’s pretty rare to extract a class, find testing a lot easier on it, and then, at the end, come to regret extracting the class.  When you find yourself banging your head against the wall in a growing iceberg class, extract!
  • Refactoring to clean code makes it a lot easier to hit the ground running when you come back to your code after a while.
  • The goal of test driving a production code base is not to address all possible inputs to the thing under test.  You test drive until the implementation is done.  If you continue to write green tests after that, you’re no longer test driving.  There’s nothing wrong with this activity, but take care that you’re not adding cruft instead of value to your code base.
  • I wrote maybe 10 tests to drive the implementation of castling for white pieces, and then something like 3 tests to make it also apply to black pieces.  This is normal.  Just because I wrote 10 tests to get 50% of the functionality does NOT mean that I have to write another 10 tests to get the other 50%.

By

ChessTDD 52: The Simple Beauty of Refactoring

In this episode, I decided to be content with the simple beauty of a refactoring.  I’m on the road and quite busy, including some presentations and a lot of driving around to various client sites, so it’s already a tiring week.  Add to that the fact that my car stereo is (was) apparently a hot commodity on the black market, triggering a thief to target my car in the Marriott parking lot while leaving every other car alone, and it’s been a pretty draining week.  So to sit down and code was nice.  But to sit down and clean up/delete code was sublime.

It’s always a win when you can do some cleaning, and so I decided to cap an episode early with nothing but that activity.

What I accomplish in this clip:

  • Refactored GetCastlingMovesFor to be cleaner and more succinct.
  • Laid a solid foundation for implementing castling for black pieces.

Here are some lessons to take away:

  • Trust me — you’re never going to look back later and think, “if only I hadn’t spend those 15 minutes cleaning up this method!”  Take the time.  Clean the method.  You are definitely not going to regret doing so.
  • Avoid “magic” values whenever possible.  Ask yourself if someone reading through your code would say “what on Earth does 7 mean here?”  Take literals and given them meaningful names as constants to be clear on their significance.
  • Code is a lot easier to reason about when it is declarative, rather than imperative.  Whenever possible, write code that expresses “what” and not the details of “how.”
  • It’s okay to give something a temporary nonsense name if you’re in the midst of refactoring and think you might not be done conceiving of what it’s supposed to do.  Just make sure you come back and give it a good name.  Don’t forget!