St. Pauli school of TDD
Test-driven development is designed to provide feedback at intervals of seconds or minutes on whether current software development is making progress in the right direction. If the development takes too long until all tests can be run again without errors, this feedback is missing and a slower development speed is the result. We often notice that many developers are still able to handle the first two or three TDD cycles smoothly, but the subsequent cycles are so slow that one can hardly speak of test-driven development. We have therefore developed a systematic approach that leads to continuous progress in short TDD cycles. Following the two well-known TDD approaches - "Chicago school" and "London school" - we have named this approach St. Pauli school of TDD.
Start on the API-Level
Grow slow and steady
Delegate subproblems to stubs
Replace stubs recursively
Finish off with a validation test
Treat test suite as append-only
You can find a more detailed description of the approach on the website.
To demonstrate the St. Pauli school of TDD, we choose the BankOCR-Kata and start with a test at the API-level.
We enter the first TDD cycle with a failing (red) test. We are therefore in the red state.
To get as quickly as possible into the green state, we simply return the expected value.
What we did is both part of the Fake-it- and the Triangulate-Pattern. If we refactor the constant value to the real implementation, we would have used the Fake-it-pattern. But this would be a too big step at this point. That is why we continue with the Triangulate-pattern. With this pattern, we add more tests until returning hard coded answers gets ridiculous and the real implementation gets more obvious.
Again, we do the simplest thing to get back in the green state.
We do not expect to gain any more insight to the problem from the API-level, so we continue with the second part of the "Fake-It" Pattern and refactor the hard coded pard in small steps towards the real implementation. These small steps are also called baby steps.
Here, we identified a subproblem: The scan is converted into text digit by digit. We delegate the responsibility to convert a multiline string to a digit string to the method
convert_digit. We use the
todo method to introduce the call to
convert_digit without breaking any tests.
To split the large multiline string into something, that the
convert_digit method can work with is another subproblem. We delegate the solution of this subproblem to the
split_scan method. Again, we use the todo method to introduce the usage of the new method without leaving the green state.
The St. Pauli school of TDD defines a recursive approach. The
split_scan function is now the new SUT and we start again with a most basic API-test. We deliberately choose a different test input than in the tests before to make use of simpler examples.
To get back in the green state quickly, we use the "Triangulate"-Pattern again.
We start to refactor the hard-coded solution to something that is slightly closer to the real implementation.
The next step is rather large to avoid bursting this notebook. In reality, there have been a lot of small baby steps, each of them a little bit closer to the solution.
We complete our first St. Pauli TDD cycle by finishing with a validation test.
split_scan is now ready to go, so that the todo function around
split_scan can be removed.
We duplicate the working code for the all-ones-case. Still, we are in the green state.
convert_digit method, is so straightforward, we do not need to write a standalone test. This approach is called "Obvious Implementation". As a rule of thumb, we only use this pattern when writing the real implementation is faster than an average TDD cycle.
Now we can expand the
convert_digit method for 1s, 2s, etc.
There are still more digits to implement, but to cut a long story short at this point, we indicate, how a final
convert method would look like.
Visit the website for more information and an additional demo.