What is TDD? An Introductory Guide
Why TDD?
Perhaps your team is looking to shift gears and fully employ all its resources to push for test-driven development, or you simply want to get an understanding of its pros and cons.
It is important to first understand what TDD is and the goals it seeks to achieve.
Getting Started
To answer that, we must first define what testing is.
- What do we mean by testing?
- When should we test?
- What logic ought to be tested? What about the data?
Once you have an idea of these topics, you can go about creating the list of tests you want to implement.
How should you go about creating this list?
Firstly, list all the operations that you know will need to be implemented. For operations you are unsure will exist, you can create a blank version(simple return function) of it to keep track for the time being. Finally, we must consider the refactoring that will have to be done to produce the clean code in the end.
You’ve made your list of tests you expect to implement. Now when should you start writing those pesky tests and assertions? Before you write the actual code that has to be tested is the ideal answer, because often once you’ve written your code you simply won’t have the time to spend to go back and test.
Doing so lets us have more granular control over the design and scope of the project we are about to embark on whether that be creating your user facing frontend website or making changes to your developmental pipeline, etc.
From the 3 A’s to a Green Bar
So we start writing our tests and we come across a whole smorgasbord of problems we must tackle, such as where our functionality lies, what the expected return value of the call should be, aliasing problems, etc. Where should we even be starting?
A valuable technique to employ here would be to start with your assertions and work backwards from there. By knowing the expected outcome and comparing it to the actual outcome that came about as a result of our actions on the inputs we can trace its path and trajectory that led it to the result.
Fantastic, you’ve made you assertions. Now we just have to figure out where our test data will come from, what that test data looks like, and what actions we are performing on them. As a rule of thumb, you want your test data to be recognizable and easy to follow along with and if that fails, you can always fake your data using mocker functions!
Once we have the assertions and our test data defined and out of the way, we can get into the meat of testing our functions. These steps follow a arrange(test data) — act(testing functionality) — assert(assertions) design pattern giving us a solid standardized structure to our testing suites.
Another key ideal we should encapsulate when writing tests is that we as programmers are writing these tests not simply for the computer to churn out the results. We write them so that fellow programmers in the future when looking through our codebase will be able to decipher at the very least the intent of our code.
Finally, when we have ran our testing suite(eg. pytest) and the bar comes back green, we know the function does what we expect it to do. Or in the case that a red bar comes back, we can work on refactoring and getting back to a green bar.
What are the benefits of TDD?
- We will have a more modular codebase — Able to develop more incrementally and have tests to back them up along the way.
- More maintainable code — By focusing on more digestible small incremental code changes, the codebase can smoothly and naturally meet the demands of changing testing requirements
- Better understanding of scope and design — Within agile development, at the rate that projects are churned out, scope and design can be lost at different levels of development and TDD can shore up that shortcoming.
If you would like us to evaluate and review your current use-cases, please email us at info@datasurge.com or complete the form on our contact us page.