A natural workflow for software developers is to code and then conduct some manual tests to make sure things are working correctly. While this approach works, it also has some issues:
- It’s error-prone (the tests are manually conducted)
- We normally only test a small portion of the app (the part under development)
To be fair, manually testing only the part under development is not the problem. The problem is that we normally don’t conduct all previous tests for the other features. We might introduce a breaking change without noticing it.
Beyond manual tests, there are other tools we can use to ensure the correctness of our code. One of them is unit tests. They ensure each component in our code performs correctly in isolation, increasing the overall quality of the software we write.
TDD is a workflow that builds on top of automated tests in general. I don’t think it works in every scenario, but when used with unit tests this technique shines:
- It gives us instant and reliable feedback on the changes we make
- It disciplines us to write tests covering the features we develop
- We are informed if we break an existing functionality
I’ve used TDD in the second and third assignments of the CS193P course. These assignments ask the students to build two card games for iOS. I began the development by the model (which contains the game logic), and I didn’t need to write the UI layer to only then manually test the business logic. Having the tests in place also gave me confidence that it worked. Here is a commit that shows this workflow in action (Each feature has some related tests ensuring it works).
It’s hard to use this technique if:
- We don’t have a good understanding of the project
- We have a tight schedule
- We are writing UI or integration tests (those take time to write and run and might give different results)
Many of TDD’s benefits come from the fact that it enforces us to write automated tests. If we get into the habit of always writing tests for the changes we make, we are also in a good shape.