Brett Schuchert gave a presentation on bringing in testability to your code at the Agile Testing Days. This is my write-up of the presentation.
Brett Schuchert spoke about design in the sense of code design in order to test it. Schuchert presented a simple dice game with two dice. The rules consisted of rolling two dice. When the sum is above seven you win, if the sum is seven it’s a push, and you lose when the sum is below seven. In his code design the dice were out of control. So, in order to test the game setup, the underlying question was how to test this simple system.
Schuchert introduced scenario-based testing as a solution. When possible the focus should not be on the mechanism, like rolling the dice, but instead in terms of scenarios. In the changed design, he then used a loaded die, which could be used to control the face values of the die in the game in order to test it. Such a loaded die is called a test double, where the result of rolling the die matters for the test writer. The problem then became to inject the dice into the dice game.
The underlying principle is dependency injection. The restructured design uses pre-created dice that are injected when the dice game is created. So, in order to test the dice game, two loaded dice are created with a predictable result, and then fed into the game, so it becomes testable in this regard.
In an jeopardy manner he made the point for reproducibility about questions. On of his points was that the ratio of reading code to writing code is more than 10 times according to Robert C. Martin. Another answer presented was 66%, which yielded Weinberg’s QSM question: “What is the chance that a one-line defect fix will introduce another defect?” He raised the point that a side-effect using TDD is having a fully automated test suite which helps to do even large changes in a complex system with knowing that you didn’t break something in the code.
Schuchert explained TDD as a design practice. He said that TDD comes from the late 50s at the original Mercury Rocket Project. At that time computers were rather expensive compared to the inexpensiveness of people. The NASA people used scenarios, calculated them by hand, and then implemented the system.
The next example Schuchert worked through was an RPN calculator which uses postfix notation for the operators in mathematical calculations. The audience collected test ideas and design ideas to support testing of the RPN calculator requirements. Among them were logging functionalities, a scriptable API, as well as applying patterns.
Schuchert worked through a first set of requirements using plus, minus, multiply, divide and factorial in an implementation of the RPN calculator. He motivated the iterations using example to describe what the system is supposed to do. He showed a scriptable way to test the application using the examples, since the examples where already using FitNesse like notations.
Schuchert closed with that it starts with dependency injection, but it’S really about design. Find out the problem statement, then it’s easy to test, design and code. If it’s important to check, then it’s worthwhile to state it as a concern in the code as well.