2025 Public Training Schedule
January 14 – 17, 2025 – Agile Analysis and Design Patterns – Half-Day Sessions
(c) 2024 To Be Agile
Although I am an advocate of test-first development, I also acknowledge that there’s a bit of a conundrum in the name test-first development. How can you write a test for something before you write the something? There’s nothing yet to test so how can it be a test?
The answer to that question is that it’s not a test. It just looks like a test. How can it be a test if there isn’t anything to test? Calling it a test at this stage before the code it’s supposed to test is written is a bit of a misnomer. So then what is it?
At this point, I’d like to think about it as a hypothesis. We’re hypothesizing that when we write the code it will behave as we intend it. We’re also hypothesizing that the way we call the routine we want to test is embodied within the test, as well as what we’re expecting to be returned. I think of my test as a hypothesis and the code that I use to make the test pass as my experiment, which proves or disproves my hypothesis.
To me this makes sense. Scientists don’t randomly mix things together in the laboratory. They run experiments and their experiments are based on a hypothesis that they are trying to prove or disprove. It would be reckless to try to run a scientific experiment without a hypothesis or something that you’re trying to prove or disprove. I say that it’s equally reckless to write code without knowing what your goal is. Far too often, the goals of writing code are not explicitly clear to us. This is the reason that most software developers write more cruft than actual working code.
How many times have you boarded a flight without knowing or caring where it was going? Never, I hope. And I hope the same is true when you code. Having a clear sense of what we’re trying to accomplish when we’re writing software drives us to get the job done and keeps us from getting lost. I find that when I do test-first development that my tests serve that purpose and keep me on track and focused so that I’m only building valuable software and the amount of cruft that I write is minimal.
Therefore, the role of a test when we’re doing test-first development is actually dual. A test has two purposes. When we first write the test it’s purpose is to assert a hypothesis and then when we make the test pass it becomes a real test that provides value for us evermore by verifying a behavior is working as expected.
The unit tests that I write when I do test-first development allows me to regress behaviors in a program and prove that it works whenever I make an even minor change to the code base. That level of confidence is priceless. My tests have my back, so to speak, and have saved me far too often than I can count. I find that I’m able to take far more risks in my code because I know if I make a mistake that my test will likely catch it and I’ll have the opportunity to fix it immediately before anyone else sees what I did.
Of course, to have a high degree of confidence in my code and my tests, I can’t just write any tests. I have to follow a methodology to support me in writing reliable tests. These are learnable skills if we’re willing to learn them. And once we master these skills development gets a lot less stressful and a lot more fulfilling.
Previous Post: « Why Write the Test First
Next Post: Don’t Write All Your Tests Upfront »