During development, we end up having to write so many different types of tests. Seems a bit too much, but I believe it is not. Every test is testing “something”. If the “something” is not clear, maybe the test has no purpose. It exists over having to write tests.
Unit tests are the most common. The classic definition of unit tests is test “the smallest possible unit”. The “something” is “the smallest possible unit”. Some say it’s TDD. Unit tests are meant to test code in a very fined grained level. So we narrow it down the smallest possible unit, to make the task easier and feasible.
TDD means “Test-driven Development”, not testing “the smallest possible unit”. It’s thinking about each possible scenario. Then think on how to test it. Only at the end, how to implement it. One test at a time. What to solve, how to test, how to solve.
The TDD mantra is: Make it red. Make it green. Refactor. Repeat for every single test, until we believe all the requirements are fulfilled. I could start talking what about best practices and good example of tests. I rather focus on another thing: Us.
When TDD is properly done, it’s a cycle: write test – run tests; write code – run tests; refactor – run tests. We are constantly running the tests. When it’s the CI server running them at the end, it’s OK if it takes longer. But if we are in the middle of process, it’s not the same thing…
Imagine we are implementing the Fibonacci sequence:
- Scenario Fibonacci(0) = 0
- Scenario Fibonacci(1) = 1
- Scenario Fibonacci(2) = 1
If we are writing a unit test for each scenario, in a TDD way, this is intended to be done in fast cycles, so we won’t loose ourselves with other things. We focus on what we want to achieve in little steps: “STEP Fibonacci of 0 is 0. STEP Fibonacci of 1 is 1. STEP Fibonacci of 2 is 1…”. Each iteration we run the tests at least 3 times.
Imagine having to change tabs, minimize a window and maximize another or, even worst, write a command line every time to run the tests. Think fast: What problem are we working on?! We have to stop and think. Less than 40 words were enough to drifted our minds away from the problem. Beside getting more tired with the context shift, there is a big change we distract ourselves and reach the Fibonacci of 12. That is a lot of redundant tests.
You say: “My IDE is great! No tab change, no command lines, just a key press to run my tests! Don’t see your point.”
I’ve seen “unit tests” where a big chunk, if not all, of the application is started; a considerable amount of logic involved; starting a server; doing HTTP requests and asserting the response; reading files. Any of those things take time, much more than 1 second. The IDE tries to makes it easier, but we make harder, longer.
Are people really doing TDD or just having to write unit tests? Writing unit tests after the code makes it loose much of its purpose. After watching a movie, do you stay and watch the closing credits? After writing the code, do you want to write the tests? Only if you have to.
It’s not about unit tests and test “the smallest possible unit”. It’s about TDD, “Test-driven Development”, and letting tests guide our coding. Tests need to be fast, because we are constantly running them, over and over again. It becomes tiring, counter-productive and painful if it takes a noticeable time for us humans to get feedback. If it’s painful, we do it less or try and avoid it. Human nature.
When writing code, in a TDD manner, take great care of test code. Tests will have to be maintained and are documentation. Be critic and practical about it. Avoid unnecessary logic. Worry about making it simple and obvious. Everything will become much simpler and faster.
If you are doing TDD!