DEV Community

loading...

My Experience With Test Driven Development (TDD)

Russ
Software Engineer
・4 min read

What is Test Driven Development (TDD)?

TDD is a software development approach in which a test is written before writing the code. Once the new code passes the test, it is refactored to an acceptable standard. TDD ensures that the source code is thoroughly unit tested and leads to modularized, flexible and extensible code. It focuses on writing only the code necessary to pass tests, making the design simple and clear.

Unlce Bob has three rules for TDD:

  1. You are not allowed to write any production code unless it is to make a failing unit test pass.
  2. You are not allowed to write any more of a unit test than is sufficient to fail, and compilation failures are failures.
  3. You are not allowed to write any more production code than is sufficient to pass the one failing unit test.

My Experience

What I'm Working On

I'm refactoring a project of mine to use SQL instead of NoSQL and I was going to do certain things a little differently so I decided to rewrite my whole backend.

First Thoughts

I was completely lost about where I needed to start because I was thinking "how could I reference something that doesn't exist?" but then I'm like "oh duh the test will fail so then I would need to create all those files to make the test pass".

How I Immediately Broke The Rules

I started by forking a boilerplate that I had created and created the basic files .env, error-handler.js, logger.js, validate-bearer-token.js and set up the test file. Looking back now I think I immediately broke rule #1 because I wasn't trying to pass any test and later on I corrected this by not creating files until I had a test asking for that file.

The next thing I proceeded to do was create my SQL files and get my schema's defined and add the correct npm packages to make my database connection work. I decided to define my schema before writing my test for it because I need to see what query strings I would be writing and have it all defined in one place so that I wouldn't be going back and forth on my tests. I believe this breaks rule #1 as well.

My First Test

My first test was simple and I was able to make it pass very easily. I was testing that my empty database responded with an empty array.

My Second Test

My second test would insert data into the database and it would respond with all the data that was just inserted. The test immediately failed because of a schema design flaw from my end. I had circular references in my tables. In the business table, I had this column: address_id UUID REFERENCES address(business_id) NOT NULL UNIQUE and in the address table I had this column business_id UUID PRIMARY KEY REFERENCES business(business_id) NOT NULL. This would require that both tables be created at the same time to even make the insertion possible.

I was thinking that my second test should be just as easy to make it pass but it showed me that I couldn't even design my schema correctly and I spent a lot of time rewriting and rethinking the design of my schema. It showed I still had a lot to learn about SQL schema design and I was able to learn a lot about schema design from the dev community on slack.

The Tests After

After I had defined my schema correctly, writing the tests after seemed so much easier and required less research on how to set things up correctly.


Conclusion

I believe using TDD would have saved me a lot of time by not doing a lot of manual testing each time I made a change to my schema or code. The test will do the comparing for you and immediately tells you why it's failing.

Using the TDD approach allowed me to dictate how I wanted to see the response from the server and then writing and rewriting the code to make it pass. It showed me the areas that I was shallow on as a developer and it made me go out and learn more about that particular subject just so I could make my test pass.

TDD will immediately show you how well you know what the response should look like from the server. Still being an entry-level developer it has shown me that I still have a lot to learn about how Postgres responds and how it inserts data. Sometimes I had to console.log responses just so I could write the tests and know what to anticipate from the server.

I see the TDD approach very beneficial to helping entry-level developers become better developers and will make my best effort to continue using TDD in my projects.


HELP WANTED: I'm not much of a writer so if you know of good articles that helped you become a better blogger on dev.to please do share them with me in the comment section.

Discussion (12)

Collapse
rossholloway94 profile image
Ross Holloway

There are some interesting thoughts here.

I think immediately "breaking" rule 1 is sometimes necessary. For example, if I am writing unit tests in Java, most of the time I'll need to create some POJO / model classes to be able to write and compile the unit tests in the first place.

Also, I think you should be careful with this approach to TDD. While what you did made sense, because there is a connection to a database, this becomes more integration testing as opposed to unit testing. Mocks come into play here so that integrations can be mocked and therefore unit tests stay de-coupled.

Collapse
russ profile image
Russ Author

Greatly appreciate the tip regarding mocking my connection to the database, I'll have to look more into it.

Collapse
togakangaroo profile image
George Mauer

I recently wrote about a tdd workflow that goes beyond simple exercises. You might be interested georgemauer.net/2019/12/02/tdd-wit...

Collapse
russ profile image
Russ Author

You broke it down very well, thank you for sharing the article :)

Collapse
russ profile image
Russ Author

Thank you for the link :), I'll have to read it.

Collapse
davinaleong profile image
Davina Leong • Edited

Just curious, what testing framework are you using?

For a suggestion, I recommend Jest. It's maintained by Facebook.

Collapse
russ profile image
Russ Author

I'm using Mocha + Chai on the backend and Enzyme on the frontend. I've been thinking of using Jest on the frontend. I'll be refactoring my frontend as well so I will be giving Jest a try.

Collapse
davinaleong profile image
Davina Leong

I've tried Mocha + Chai too.

What I like about Jest is it's simplicity of use... no setup or configs required...

Thread Thread
russ profile image
Russ Author

I'll have to look into it a bit closer, thank you for the suggestion :)

Collapse
ngarbezza profile image
Nahuel Garbezza

Great article, thanks for sharing! I've been doing TDD for many years and I shared some useful tips in this article: dev.to/ngarbezza/6-tips-for-a-powe...

Collapse
russ profile image
Russ Author

Thank you for sharing that with me, I'll have to read it :)

Collapse
russ profile image
Russ Author

Loved those 6 tips, thank you :).