DEV Community

abdelouahed ELHARIRI
abdelouahed ELHARIRI

Posted on

Write better software with Test-Driven Development!

First some Context :

After years of struggle spent writing applications with a never ending stream of bugs and no clear boundaries, a giant big mess that made my anxiety kicks in whenever i had to touch or even think about it, the pandemic hit, finally giving me enough courage to quit my job and step back to learn - this time - the fundamentals of software engineering instead of continuously grazing new fancy languages and tools.

I started by looking for what veterans in the field (uncle Bob, Kent Beck, Dave Farley, Martin Fowler… to name a few) are saying. I listened to hours and hours of their talks and read their most recommended books. I was learning a lot.

Quickly, i noticed that all of them were bringing TTD up as a must, insisting that it is crucial to writing good software. As your average developer, i, of course, kept neglecting their advice simply because it was seldom requested in the market (SAD but true). However, after weeks of resistance i finally gave up and started learning about it.

At the beginning, the idea seamed so foreign to me, but after a couple weeks of practice i started getting the hang of it, soon after everything changed. The quality of my work and my self esteem improved so much so that i pulled the courage to wright my first blog ever in order to invite you to try it, and share everything i learned after almost a year of practice.

Now into the real stuff:

First bear in mind that TDD is not hard, AT ALL!! It is a lot easier than you would expect. The whole idea, is about a simple premise :

write your test first before writing ANYTHING else.

To use it in a project you will need just a simple testing library (like JUnit for java, jest for js…) and the process is pretty straightforward :

1. Write your test first: try to be simple and straight forward, do your best to not tackle the whole complexity at once. Please give your tests the importance they deserve, they will serve later as an insurance that everything is working as expected (you certainly don’t want your insurance to be flawed).

2. Make it fail: most of the time, the test will fail as soon as you run it for the simple reason that what you are trying to test is not there yet, BUT!! sometimes it doesn’t. This is usually an indication that there is something wrong going on, either with your tests or code. Take the time to figure out and fix the problem by making all the tests pass except for the one you are writing (you will be surprised by what you might find).

3. Write just the necessary code to make it pass: Once again, try to be simple and minimalistic about it, write just enough code to pass your test. Do your best to resist the temptation to tackle everything going in your head.

4. Make sure that all the tests are passing : if one of the previous tests has failed this means that you’ve broken something. Generally, this is a good indication that your code needs some refactoring. so pause and take the time to tidy up your application before going any further (once again, you will be surprised by what you might find).

5. Refactor your code from time to time : Take advantage of this INCREDIBLE new possibility you’ve unlocked. having a reliable tests suit allows you to comfortably refactor your code from time to time. You can easily trust your new code when every test is green again.

6. Repeat : Repeat this process every time you want to write new code, don’t be tempted to skip it.

And thats all, if you understood these simple steps then you’re ready to start using it immediately. However, This is a major shift from the traditional way of writing applications and can be quit confusing at first. TDD is very easy in itself, it is the shift that will be challenging as we are naturally reluctant to change. But trust me, if you feel somewhat intimidated at first, please don’t give up. TDD helped a lot of average developers like myself to step up their game and write better software and i am sure that whatever your level may be it can only be beneficial to you and your organization, It will just take some time to get used to.


If by now you’re wondering how will this will help you become a better programmer, then the answer:

In an unexpected way, TDD encourages good design and boosts the developer trust in his work.

TDD drives good design by :

- Making us think in the shoes of our application client/consumer (a user, another application or programmer) first : Generally, thinking about the interface is the last thing we do as developers, resulting in a poor user or developer experience. Writing tests first pushes us to think about how a consumer will be happy interacting with our application thus making much better APIs.

- Enforcing overall better and cleaner architecture : Writing good and reliable tests requires isolating our components (modules, classes, functions…) and clearly defining their boundaries. For example not isolating the DB storage logic from our business logic will make testing the later very hard. Instead of simply mocking the database behavior, we will end up dealing with all the complexity of managing the state of the database records, connection, clean up… before, during and after tests.

- Encouraging working in small steps : Writing a test at a time helps thinking in little steps. Focusing on one little thing at a time instead of tackling the whole complexity of a feature at once.

- Making refactoring much easier : because we will have a layered architecture, a modular design and a reliable test suit that fails every time something is broken, we will be able to confidently and frequently refactor our code in small incremental steps knowing that we can trust it again when all the tests passes.

- Encouraging leaner code : TDD makes us write just enough code to answer our clients need and nothing more, making us leaner and sparing us from writing a lot of code just because we taught that it was a good idea.

TDD boosts our self esteem as programmers :

constantly knowing that we are able to deliver good software while keeping it behaving as expected and that we can always improve its design and architecture literally changes our life. We become :

  • More confident talking to our boss, client and teammates about our work and defending it if necessary.

  • More open to learning new stuff and change in general.

  • nicer to your coworkers and more of a people person.

Random points :

- TDD vs Traditional testing : It is hard to write reliable tests after writing the code, it is very hard to resist not writing ones that are partially designed to make our code pass especially under pressure. furthermore, these tests don’t offer any of the advantages cited above.

- TDD vs BDD (Behavior-driven development) : i don’t actually think that they should be two separate things. The way i see it, BDD just describes how to use TDD pushing us to focus more on the expected behavior/outcome not the implementation. Tests should focus on the what not on the how.

- “Test coverage” doesn’t mean anything : TDD isn’t about the actual implementation details, it is rather about the behavior or outcome we are expecting from our code. Changing the expected behavior should be the only reason to change a test. So we should not feel pressured to test everything we write, we test just if a component behaves as we are expecting it to.

- TDD actually makes you faster : you might be thinking that if you are able to deliver good software without using TDD then why bother at all with the extra work of thinking about and writing tests. Fair enough. However, remember when parts of your application if not all of it arrived to the point where you become so afraid to even touch it, remember the anxiety that comes with it. TDD allows to quickly detect when something goes wrong before it is too late, as well as being in a continuous process of improving your design and architecture.

- TDD vs unit tests : i can’t really say much about this comparison because i am still confused about what does unit testing exactly mean. The only thing i can say is according to the wikipedia’s definition, TDD can be considered a form of unit tests.

Final Thoughts :

I understand that things are difficult for everybody with the pandemic and everything else going on. However, Our industry is critical to the well being of society. When we do poorly, we are wasting valuable money that could have helped other people, worse still, we may end up making their life harder. TDD is just one part the puzzle, writing software is a continuous learning process and we need to make it our responsibility to improve ourselves and push the industry even further.

I hope that you’ve found something valuable in this article and if you have any questions please don’t hesitate to reach me on my twitter, i will gladly help.

my twitter in case you missed it : https://twitter.com/Abdel1hariri.

Top comments (0)