Stories about Software


Chess TDD 23: Yak-Shaving with SpecFlow

I’m writing out this paragraph describing what I’m planning to do before recording myself doing anything. This post has been a while in coming because I’ve waffled between whether I should just hand write acceptance/end-to-end tests (what I generally do) or whether I should force you to watch me fumble with a new tool. I’ve opted for the latter, though, if it gets counter-productive, I may scrap that route and go back to what I was doing. But, hopefully this goes well.

Having fleshed out a good bit of the domain model for my Chess move calculator implementation, the plan is to start throwing some actual chess scenarios at it in the form of acceptance tests. The purpose of doing this now is two-fold: (1) drive out additional issues that I may not be hitting with my comparably straightforward unit test cases and (2) start proving in English that this thing works. So, here goes.

Here’s what I accomplish in this clip:

  • Installed SpecFlow plugin to Visual Studio
  • Set SpecFlow up for the ChessTDD project.
  • Wrote a simple acceptance test.

Here are some lessons to take away:

  • There is a camp that favor ATDD (acceptance test driven development) or “outside-in TDD” and another that prefers “traditional” or “inside-out TDD.”  I’m not really in either, but you might find that you have a preference.  Both approaches are worth understanding.
  • What I’m doing right now, for the moment, is not test driven development.  I’m retrofitting acceptance tests to bolster my coverage and see if the more micro-work I’ve done stands up to real world usage.
  • If you want to see how someone that doesn’t know SpecFlow gets it set up, this is the video for you.
  • If you’ve been tinkering with a test for a while and the test was green the whole time, how do you know you’re done?  With your assert in place as you think it should look, modify it quickly to something that should fail and confirm that it does.  The idea here is to make sure that your modifications to the test have actually had an effect.

Newest Most Voted
Inline Feedbacks
View all comments
Peter Stuart
Peter Stuart
9 years ago

Great series so far. I was wondering if you could explain more on technical debt and if possible explain what it is and any examples in your codebase.

Erik Dietrich
Erik Dietrich
9 years ago
Reply to  Peter Stuart

I’ve put a draft in my folder for talking about technical debt and what it means. That’s not a brief topic, but let’s say for brevity purposes here that tech debt is generally, “that implementation could be better/clearer/simpler but I’ll worry about it later.” It’s the notion that you’re bounded by a time constraint that prevents you from doing it “the right way.” In the ChessTDD code base as it exists today, an example includes the kludgy setup around fully populating a chess board. Initially, I needed it in a test class, so I did it there. Then I needed… Read more »

Drew Hannay
9 years ago

Can you talk a bit about helper methods in your tests? In KnightTest, you added a GetMoves(int x, int y) helper method that seems like it would be useful in all of the Piece test classes. I’ve gotten the impression that you don’t like the idea of having utility classes for your tests but is it really preferable to duplicate a method like that in all your tests or worse, (in my mind) have inconsistent tests where some use the helper and some don’t?

Erik Dietrich
Erik Dietrich
9 years ago
Reply to  Drew Hannay

Some years in the past, I had unpleasant experiences with utility classes in test projects that led me to avoid them. It was never really an explicit decision but a matter of practice. Here are some of the drawbacks I’ve found, off the top: * Indirection makes tests hard to grok on sight — you need to open up another file to understand a test. * Sufficiently complicated setup to require an object model in your test code is usually a design smell. In other words, if I’m finding a need to create such classes, the solution isn’t to create… Read more »