1

I was saved by Test Driven Development

 1 year ago
source link: https://www.worthe-it.co.za/blog/2023-02-09-i-was-saved-by-test-driven-development.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

I was saved by Test Driven Development

Abstract

This is a short story about how I gained a new appreciation for Test Driven Development.

I have two children. My second was born about a year ago. Now everybody warns you before your first kid how tired you're going to be. How you're going to be up in the middle of the night. When the second is on the way, you assume that you know what you're in for. I learned the hard way that it's much harder with two! You can't sleep when the baby sleeps if you also have a toddler to look after.

About a month after my second child was born, I needed to go back to work. Being tired meant that I had a short attention span, I was easily distracted, and I couldn't keep as many details in my head as I usually would. Foolishly, I still picked up the next most important feature on the team's backlog, and it was a complex one.

So I had a complex issue I needed to get done, and I wasn't thinking very well. I needed a plan. My saviour ended up being Test Driven Development.

What is Test Driven Development

Test Driven Development (TDD) is a way of writing software where you write automated tests as an integral part of the software design and development process. Specifically, it's a test first methodology, where you constantly write a small test for something that isn't implemented, then implement it.

The TDD cycle is only three steps: Red, Green and Refactor.

  • Red: Write a test (or update an existing test) to demonstrate the thing you want to be different. Run the test to verify that it actually tests what you're trying to change, and that it fails for the reason you think it should. Often in compiled languages it won't even compile at this point, because you write the test against the interface that you want to exist, not necessarily the interface you already have. This is usually called the "red" phase because most testing tools will highlight failed tests in red.

  • Green: Make the smallest change you can to make that test pass without breaking any of the other tests. It's fine at this point if the code is messy, doesn't solve the whole problem in a completely general way or has lots of duplication. Most test tools will give you a green summary if all tests pass, so this is the green step.

  • Refactor: Clean up any sins which were committed to get the tests to green. For example, if you copy pasted some code to get to green, this is the phase to remove the duplication. After this, the tests should still all be passing, since refactoring should maintain the same functionality.

On the side, you keep a list of missing functionality so that you can focus on one thing at a time without losing track of the big picture.

In a broader context, TDD is also often associated with Extreme Programming. The practices of extreme programming include writing automated tests and writing them before writing the code they're testing, so proponents of Extreme Programming will also generally support TDD.

I haven't quite followed a strict test first methodology up to now

I wouldn't claim to be a TDD expert. I admit that I haven't always written my tests before the code it's meant to test. I do generally write tests, but I haven't always strictly added an automated test when I felt a feature was trivial.

However, I am fortunate enough to have worked with people who were evangelical about TDD. I'd already learned the steps of TDD. I'd done training courses like Code Retreats facilitated by fantastic software engineers to practice TDD.

In other words, I had TDD in my tool belt even if it wasn't part of my daily practice.

How did it save me?

Coming back from paternity leave, I was tired. Sleep deprivation is a better word for it. Also, since I work from home, I still had regular baby distractions. I really liked that I could still be around my family while returning to work, but I couldn't rely on my usual ability to keep a lot of moving parts in my head anymore. Instead, I pulled out TDD, and used it to chunk the work down into tiny manageable pieces.

I started with writing a TODO list of tests which I felt I would need. In this case, it was just unimplemented tests right in the source code. Luckily it doesn't take much sustained focus to write a list like this. You can jot them down in any order, and keep adding to the list later as new ideas occur.

Then, I picked just one test case. All I needed to do was write the code to demonstrate what that part of the functionality should do. I don't need to implement the functionality itself or anything, just the test.

Watching it fail was an important step. I was writing JavaScript, and there's a bunch of ways to accidentally write tests that don't assert anything. For example, you might forget to await a promise, and assert that that promise itself is truthy rather than its result. See the test fail, and check that it fails for the reason you think it should fail.

Next, I implemented just enough code for that one test. I didn't do something silly like return hard coded wrong results, but I also didn't bother to think too far ahead. I just needed enough focus to get the one test passing.

When the test was green, I knew that feature was locked in. If I accidentally broke it (and I did accidentally break it), I would know about it immediately and could change course.

While working, I did come up with new tests I would need. I added them to my TODO list of unimplemented tests. When I'd implemented all the tests, and they were all passing, I knew I was done! That code has been fairly stable, even though I wrote it when I wasn't at my best. Personally, I have a new appreciation for TDD, and use it more than I did before as a default way of working. Maybe I don't need it when I'm at my best, but it really helps me to keep the quality up when things are rough.

Wrapping up, how can you learn more?

So that's my story. I now try to be more disciplined about working in small verifiable steps by writing one test at a time and implementing it.

If you want to learn more about TDD, I'd recommend starting with Kent Beck's book, Test Driven Development By Example. There are many resources about TDD online, but this book is the best one I've found so far to go in depth explaining what TDD is and how to practice it.

After that, go looking for people practicing TDD on systems similar to yours. Same language, same type of application, etc. I've gotten some great insights about writing tests in Rust by reading Matklad's article "How to Test".

I hope that you too take inspiration from my story to try out Test Driven Development, even if you've tried it before and it didn't stick.


If you'd like to share this article on social media, please use this link: https://www.worthe-it.co.za/blog/2023-02-09-i-was-saved-by-test-driven-development.html

Tag: blog


Related Articles

Software Engineering is Engineering

I believe that software is an engineering discipline. In this article, I make that argument by summarising the work of a few other authors who have written on this topic, and offer my perspective on why this terminology matters.

Property Based Testing

Property based testing is a useful technique for testing software. In this article, I discuss property based testing, and show an example of how I used a property based testing approach when competing in the Entelect Challenge.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK