DaedTech

Stories about Software

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!

By

ChessTDD 51: Getting Castling under Control

Editorial Note:  These videos appear on my Youtube channel, but I’m starting to do a lot of other things there as well, including an upcoming series that I’m going to start uploading soon.  If you like the series, it’s probably worth subscribing to the channel.  You can subscribe by going to this link and clicking “Subscribe.”  

After flailing around a bit in the last episode, this one was a little more fruitful.  Castling is now somewhat more under control, and it seems like things are progressing along a good path.

What I accomplish in this clip:

  • Added more robustness in the non happy path scenarios around the new CastlingStatusChecker.
  • Got negative cases working for king and rooks having moved on the white side.

Here are some lessons to take away:

  • Don’t get married to implementations.  Keep things light so that you can modify your approach as it makes sense.
  • When it comes to collaborators in a class, reason about your preconditions on those collaborators (e.g. they can’t be null).  Check for problems in the constructor so that you can fail more closely to the problem than if you limped along and failed only when someone subsequently called a dependent method.
  • As has been mentioned a lot in the past, make sure that you take appropriate time to pick good names for things.
  • Experiment with your methods, trying on different local assignments and such, to get your code as readable as possible.  Hard to know what you’ll find readable until you actually see it.

By

Chess TDD 50: Back to the Green Field (Kinda)

Editorial Note:  These videos appear on my Youtube channel, but I’m starting to do a lot of other things there as well, including an upcoming series that I’m going to start uploading soon.  If you like the series, it’s probably worth subscribing to the channel.  You can subscribe by going to this link and clicking “Subscribe.”  

This time around, I actually get to do a bit of green field development again.  That sounds like a weird distinction to make, but I’d been so involved in modifying the existing pieces and the board class that biting the bullet and creating a class to handle castling was a huge relief.  I had fun this episode — so much so that I already coded 51.

What I accomplish in this clip:

  • Created a class to evaluate boards for castling opportunities.
  • Started the castling implementation in earnest.
  • Proved to be really bad at telling X and Y coordinates apart.

Here are some lessons to take away:

  • As with assemblies and namespaces, having dependency cycles with classes is a bad idea.  If class X knows about Y and Y knows about X, these should probably be the same class.
  • When testing additional scenarios is a huge chore and you’re frequently having to worry about breaking lots of other tests, it may be an indicator that you’re cooking up an iceberg class.  I noticed this in the form of pain I felt when doing things to the Board class and the comparable joy I felt in this relatively green field work, today.
  • Tradeoffs are everywhere in your software development process.  Refactoring while red is a risk, which I did without thinking to rename a method parameter.  But not renaming the parameter is also a subtle risk because I might forget to do it while getting to green and leave a sub-optimal name in there, possibly causing a future developer to make a mistake.  This is not to excuse my own mistake, but rather to point out that there tend not really to be “right” and “wrong” as often as we think.
  • It’s really easy to make dumb mistakes and we all do and will.  TDD as an approach is so helpful because it mitigates the dumb mistakes by shortening the feedback loop between when you make them and when you notice them.