« All Episodes

Adding tests to a big untested codebase - Where do I start?

Published 1/11/2019

Where do you start when you're adding tests to an untested codebase? That's what we're talking about in today's episode of developer tea.

Get in touch

If you have questions about today's episode, want to start a conversation about today's topic or just want to let us know if you found this episode valuable I encourage you to join the conversation or start your own on our community platform Spectrum.chat/specfm/developer-tea

🧡 Leave a Review

If you're enjoying the show and want to support the content head over to iTunes and leave a review! It helps other developers discover the show and keep us focused on what matters to you.

🍵 Subscribe to the Tea Break Challenge

This is a daily challenge designed help you become more self-aware and be a better developer so you can have a positive impact on the people around you. Check it out and give it a try at https://www.teabreakchallenge.com/.

Transcript (Generated by OpenAI Whisper)

Imagine yourself sitting in a stand-up meeting or a sprint planning meeting or whatever kind of meeting that you have with your team and discussing an initiative. Your team has taken on a legacy code base or perhaps you've run really fast at creating a product. And unfortunately, as a part of that, the team didn't add tests. And for whatever reason, we aren't here to judge why the team didn't add tests. We aren't here to judge the legacy code, but we are here to improve. And so as you're sitting in this meeting, you or maybe a team member, maybe the whole team, brings up the need to increase your test coverage. From zero to anything, really. And now you are faced with the mountain in front of you of introducing tests into an untested, large code base. Where do you start? That's what we're talking about in today's episode. My name is Jonathan Cottrell and you're listening to Developer Tea. My goal on this show is to help driven developers connect to their career purpose and do better work. So they can have a positive influence. On the people around them. Today's episode is a practical episode. This is not as much about the things that we always talk about on the show. But we will end up talking about how this approach, what we're getting ready to talk about in approaching an untested code base and introducing tests. How this affects or is affected by the way that you approach this. And the mindset that you have during that approach. Before we get started, I want to mention tea break challenge dot com. If you haven't signed up yet, these are daily soft skills challenges that I'm writing and releasing on a daily basis. And I encourage you to go and subscribe. It's totally free. Of course, you'll get an email when you subscribe every single day. You'll get an email with those challenges in it. You can also find the challenges on tea break challenge dot com. And the newest one goes up on that homepage every day. Go and check it out. Tea break challenge dot com. OK, so how do you approach this problem? The difficulty is that our intuition says, well, the first thing that we need to do is make this code easier to understand. We need to figure out how to refactor this code into a more maintainable state. We can see all kinds of code smells in every file that we open up. And so only once we've. Gotten the code to where we can understand it better, where we can wrap our heads around it, then we can introduce tests. Right. We need to improve the code first. And the problem with this, the problem with this is that if you try to go down this road, you are kind of walking in a minefield blindfolded and without any armor. The reality is when you put yourself in this situation, changing code becomes dangerous. Now, you'll notice. That I mentioned that this is a large code base, and that's an operative and important part of this discussion. Sometimes when we have very small projects that are untested, there may be a legitimate reason for how it ended up that way. Number one. And number two, because the project is so small, it might be a little bit easier to approach it from that refactor first perspective. Because you can hold all the necessary information. In mind, you can see all of the different pieces of the code from the top down. But when you get into a project with sufficient complexity, when you have enough information that you can't hold it all in your mind, you can't memorize it all. Testing becomes critical before any kind of refactoring. In other words, the only way that you can reasonably. Begin to refactor. Is if you have some kind of validations, some kind of testing. To warn you. To identify. When you've written some kind of refactoring code that breaks something that previously was working. But here's the key. There's different types of tests. If you've written software for very long, then you know this. The most important for the sake of this discussion are two different types. One is an integration. Test or also known as an end to end test. And the other is a unit test. The unit test is going to test more specific pieces of your code to ensure that they are working as they should. A unit test might, for example, test a specific class and its public methods. OK, so that's kind of a testing one on one idea. And when you approach a large code base that is untested. The first types of tests that you need to run are integration tests. This is a strong opinion that I have. And there's certainly valid differing opinions and different approaches that other people may take. But here's the reality. If you have integration tests that verify that your code still does the important and kind of critical jobs. Right. The critical pathways that users. Need to take in your in your projects. If you have integration tests that walk through those critical pathways and verify that whatever is on those those paths is working, regardless of how ugly those building blocks may be. You start from a position. Of having verification that the most important thing in your code remains intact, and that is functionality. If you go. Down the road of refactoring. And you write a perfect class follows all of the solid principles. And everything is beautiful from the perspective of, you know, software design, object oriented design, or even functional programming design. If you walk down that road and then something breaks, it doesn't really matter how good that that design is. If you break the code. And you leave it less functional than it was before, but with a beautiful class, then that project is worse off. And this is something that we all kind of know. This isn't surprising news. This isn't new information for you as a developer. But it is something that we often don't practice. It's kind of a weird juxtaposition. We believe that the value of our code is disconnected. In. Some way. From. The point, the function of the code. Now, that's not to say that your work on that class couldn't be leveraged into high value, right? If you cleaned up whatever it is that you broke, then certainly you have better off code. And that can be a win. But if you break something and you don't fix it, then it doesn't really matter how good the code is. At least you may haveijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijijij Logging out may be a critical pathway. Or actually, I've seen that a lot of people don't identify logging out as a critical pathway, but they do identify logging in as a critical pathway. So there's some thought experiments you can have, some good discussion that you should have with your team about which things are most critical in the application, which things should be kind of elevated, and what kind of edge case support and coverage do you want to have for those critical pathways. And build your tests around the answers that you have in those discussions. Build those initial tests. And here's the thing. Those tests should retain their working status as you go through the refactoring process. Now, it's going to be important that you refactor code to the degree that you can test it. It's possible that your product only requires those integration tests. This is very unlikely. But it may be that you can write those integration tests and then kind of stand back and things are fine. But it's much more likely that you're going to need to adjust your code in some way. If your code was not written with tests in the beginning, then it's very likely that you'll be doing some refactoring to make that code more easily tested in those unit tests and further integration tests into the future. Thank you so much for listening to today's episode of Developer Tea. This was... An unusually concrete kind of episode of this show. But if you are interested in this kind of content as well as less concrete information, like for example, practicing those soft skills that are so critical to your career and your personal growth and finding your purpose, then I encourage you to subscribe in whatever podcasting app you're listening to this episode with right now. Also, another quick plug for the Tea Break Challenge. This is teabreakchallenge.com. Tea Break Challenge.com. Tea Break Challenge.com. Tea Break Challenge.com. Tea Break Challenge.com. These are soft skills exercises that you can do on a daily basis every single day this year. Go and check it out. Teabreakchallenge.com. You can get those delivered directly to your inbox. You can also find them on Twitter at at Developer Tea. Thanks so much for listening. And until next time, enjoy your tea.