Developer Tea

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

Episode Summary

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.

Episode Notes

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/.

Episode Transcription

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 Cutrelll 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 teabragchallenge.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 teabragchallenge.com and the newest one goes up on that homepage every day. Go and check it out teabragchallenge.com. Okay 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 and 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. 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 into in 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. Okay so that's kind of a testing 101 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 it 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 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 let'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 that is breaking things. So as you approach a code base that is large or at least sufficiently complex and doesn't have tests the first tests that you need to write are the integration tests that verify all of those critical pathways. You can probably google critical pathways some of the most important ones of course you should be thinking about the most commonly used things like loading a home page that's a critical pathway logging in logging out maybe 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 you know 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 test 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 after you're listening to this episode with right now. Also another quick plug for the T-Break Challenge. This is tbreakchallenge.com. These are soft skills exercises that you can do on a daily basis every single day of this year go and check it out tbreakchallenge.com you can get those delivered directly to your inbox you can also find them on Twitter and at Developer Tea. Thanks so much for listening and until next time enjoy your tea.