ChessTDD 34: Specflow for Pawn Movement
This episode featured a return to progress toward shippable features. I refactored the first feature that I’d started to use the new, idiomatic Specflow approach. This resulted in it making the most sense to have this be the feature for pawn movement and thus progress toward implementing the pawn’s movement as well as shaking out more bugs.
What I accomplish in this clip:
- Refactored the old Specflow feature to look like the newer one.
- Deleted a bunch of now-dead code and made the Specflow backing class a lot more concise.
- Implemented HasMoved from the board perspective.
- Fixed a bug in GetMovesFrom
Here are some lessons to take away:
- I made a mistake in deleting dead code when I had a red test. Part of the reason I got this wrong was that the IDE crashed and I sort of lost my place, but there’s a lesson here. It’s easy to get distracted when you see dead/unused code (or something else similar) and go off on a tangent. That’s fine, but be sure you’re green when you go off on tangents.
- Thinking ahead about how they code you’re writing will be useful elsewhere is a double edged sword. It’s good because it can lead to more efficiency and less future rework, but it’s also the first step along the path to gold-plating. There’s no exact how-to I can offer for walking this line, but just being aware of it will help.
- When things go wrong with acceptance tests, which are coarser-grained, integration tests, your next stop in figuring out the problem will generally be to move down the test pyramid and look for more details in your unit tests. Unit tests are going to exercise the code in more granular fashion, so you should get good insights there.
- I recommend favoring domain-specific, communicative exceptions coming out of your code rather than allowing boilerplate exceptions to be thrown to your callers. If someone using your code gets an array index out of bounds exception or a null reference exception, they can’t be sure whether you screwed up in your code or whether they screwed up calling your code. If you, instead, throw “BadBoardCoordinateException”, it’ll be very clear to callers of your method that you’ve anticipated what’s going on right now, and that they’re doing something wrong.
- Deferred execution with Linq is really powerful and allows you to do some great things, but it also leads to subtle bugs. I’ve written about this in the past, even. Be careful and always remember to make sure you’re aware of whether or not you’re enumerating the sequence when you run into stuff like this.