Stories about Software


ChessTDD 28: Preparing for Idiomatic SpecFlow

This week I’m starting the process of engaging more yak-shaving, but I think it’s important yak-shaving. If we’re going to be doing this SpecFlow thing in the series, let’s get it done right. In a post I made last week, Darren Cauthon took the time to put together this gist. I read through it and my eyes bugged out. That kind of visualization is solid gold for this problem space. How powerful is it to be able to show other developers (and hypothetical business stakeholders) these ASCII chess boards and say, “look, this movement works?!” So, I’m asking you to indulge me in the journey to get there.

Here’s what I accomplish in this clip:

  • Created AsciiBoardBuilder class to take strings like “BQ” and “WP” and turn them into pieces added to a Board instance.
  • Got half-ish way through implementing that class.

Here are some lessons to take away:

  • I created something called “AsciiBoardBuilder.”  There was a time when I would have immediately thought to have it implement an IBoardBuilder interface, but I’ve gravitated away from this over the years as it tends to lead to unnecessary abstraction at times.  We can always do this alter if we need some other means of constructing boards aside from just using the Board class itself.
  • In case you’ve forgotten, one trick I use is to create the production class in the same file as the test class at first, when convenient.  NCrunch runs a little quicker this way and you don’t have to flip back and forth between two files.  I leave it in here until it no longer makes sense to, usually (e.g. when some other production class needs to use my new class).
  • I did something that’s a little more complex than your average TDD scenario, wherein I was modifying two different production classes as I went.  This isn’t particularly common and you might not want to do it if you’re new to this or you run into trouble trying it.  But if it works for you, there’s no reason not to do this.
  • If you go look up a solution, such as how to implement a bit of Linq-fu, it’s probably worth writing an extra test or two that you expect to go green just to confirm that you really understand the behavior of the solution that you found.
  • What I did with factoring out GeneratedBoard may not be to your liking.  This has the upside of eliminating duplication but the downside of introducing a bit of indirection.  For me, the improvement in how succinct the test cases are is worth it, but you may not agree.  This isn’t always an exact science — taste does factor in.
  • I’m pretty rigid about strongly favoring one assert per test method.  Not everyone feels this way, but I felt it worth refactoring to assert only one thing: that the piece is a white bishop.  (As opposed to asserting that it’s white and then that it’s a bishop).  I suggest that unless there’s really no option but to have multiple asserts, you factor toward one.