Sunday, October 13, 2024

TDDbE: xUnit Patterns

 Much more so than the previous chapters in this book, this one feels like archeology.

Write boolean expressions that automate your judgment about whether the code worked.

Primarily, the point of the automated mistake detectors is that they don't require sapience to reach a conclusion (see Back and Bolton on checking vs testing).  There shouldn't be any maybe or fuzzing of the outcomes; we're on the happy path, or we're not.

The expected value generally goes first....

Today, I read this as an indicator that the right abstractions hadn't yet emerged; we were all still thinking about the "two arguments to assert", rather than say a measurement that needs to satisfy a specification.  And of course some frameworks flipped the arguments, and finding that programmers have chosen an order that is the reverse of what the current framework uses is a common error.

I'm aware that I am swimming against the tide in insisting that all tests be written using on public protocol.

I think is "all" is a bit too extreme; also, this doesn't surprise me.  You can go back and forth on the various trade offs, but ultimately it comes down again to the fact that the tests work for the developers, not the other way around.

I was interested to note the remarks about dropping into the Smalltalk debugger, as this same behavior was an important motivation for Mock Objects.

Each new kind of fixture should be a new subclass of TestCase.  Each new fixture is created in an instance of that subclass, used once, and then discarded.

I haven't used "fixtures", especially fixtures that require explicit setup/teardown, in a long long time.

xUnit circa 2003 implemented fixtures using overridden class methods because... well, because most of the modern alternatives hadn't been realized yet.  I don't love that design, because I don't think it is obvious enough that the fixture is being re-initialized for every test call, so the class design looks like shared potentially mutable state.

Test "outlines" are now more commonly realized via nesting of contexts, so that you get a report that is a hierarchy of test results.

My experiences suggest that TestSuites are extinct in languages where the test running has access to class metadata, because everything is discovered, often with an annotation language that allows for enabling and disabling tests, or mapping tests against a wider variety of inputs, or whatever.

In summary: languages, test frameworks, and development environments have made a lot of real progress over the past 20 years; the details of how we made do without modern conveniences aren't particularly compelling.

Saturday, October 12, 2024

TDDbE: Green Bar Patterns

The chapter opens with a discussion of Fake It, Triangulate, and a light comparison of the two.

Does Fake It violate the rule that says you don't write any code that isn't needed?  I don't think so, because in the refactoring step you are eliminating duplication of data between the test case and the code.

More support for my favorite lesson: duplication of data between the test case and the code is all the permission you need to continue refactoring.

I only use Triangulation when I'm really really unsure about the correct abstraction for the calculation.

I think Triangulation really suffers from the fact that the examples typically used to demonstrate it are contrived.

Beck uses addition here, he used an equality check back in chapter three -- both are cases where you could just type in the correct implementation, rather than faffing about with triangulating.

The sorts of problems that I would expect to benefit from triangulating would be more like sudoku, or code formatting, or even line wrapping, where you may need to work in the code for a bit before you get the key insight that gives you confidence in a specific abstraction.

Sandi Metz demonstrates with "simple green" that you might prefer the duplication to the abstraction anyway.  Her advice was to prefer duplication over the wrong abstraction.

Back in Chapter 17 Kent observed that the money example went in "a completely different direction".  And as I understand it he didn't "triangulate" to choose between candidate designs - he discovered a metaphor and just went where it lead him.  This tells me that triangulation is more about the uncertainty that the abstraction will in fact be better than the duplication.

Of course, you could also try the abstraction, and then use the source control system to revert to a checkpoint if you decide that the refactoring hasn't led to an abstraction you trust.

There's no particular virtue in the halfway nature of Fake It and Triangulation.

There ceremonies are a means to an end....

  Keep track of how often you are surprised by red bars....

"Call your shots" later became a more general thing - the earliest reference I can find is Needham 2010, but he in turn attributes the idea to Kent.