It’s been quite a while since I posted my series about unit testing an existing C code base. In the intervening time I’ve implemented some tests and moderated several unit testing training sessions both for the team as a whole and for individual team members. Given this increased experience in writing tests for an existing code base that can be automated I thought you might be interested in hearing where I start the process of testing.
TL;DR — It is hard to change direction in a large ship (a.k.a. an existing/legacy code base) but you can start growing islands of tested code and getting others to help you so long as you show them how.
Document how to test in your environment
I was asked to do a training on unit testing shortly after starting at an employer. To do this, I did some basic research on the testing frameworks that I was going to use and got some tests setup on a single program on Linux. That research provided me the data to write my post about the tools for testing a C code base and, I thought, granted enough information to teach my co-workers how to test. It turns out that it only gave me enough information to get my co-workers to agree that unit testing is a good idea. That’s it. They walked back to their desks and didn’t write any unit tests.
Showing my coworkers how to test with nothing other than the agreement that automated testing is important was frustrating. But it provided me with an few lessons on how to proceed with getting testing going. To make things stick, start with the following:
- Walk through the process of setting up tests for each environment (OS, language, tool set, etc) that you build in. Document how you think the team should setup in each environment.
- After this walk a team member through adding tests in each of these environments. This will show you what you forgot to write down. Make sure that you add to your docs what your teammate had to ask about.
- After you’ve updated your instructions, check with your co-worker again to see if the instructions are better.
- Work on making them a champion for testing so you don’t have to do all of the heavy lifting with your team. The more that support testing and know how to do it, the easier it will be to get the rest of the team to commit. Peer pressure in a good way!
- Do this BEFORE you train your whole team on unit testing.
Training a team to unit test
There are a couple lessons specific to training that I learned as well. First, make sure you schedule enough time to go through the general steps written in the guide you’ve written AND give the team time to actually try writing tests. This way you can be present to answer questions and your coworkers get some ownership over testing their code.
Second, there won’t be enough time during a 30 – 90 minute training to get any difficult (read: truly meaningful) tests written. This is especially true if your teammates have never tested before. And doubly true if the code needs to be refactored before tests can be written. Your co-workers will probably only get the framework setup on a project and a very basic test setup in this time. In order to get more detailed tests on the code they’ve been working on, your coworkers work need to sit with the code they’re familiar with. Once they’ve done that they can think about how to test. This will prepare them to ask specific “how about this” types of questions. Make sure you make yourself available for this process.
Breaking Bad Habits
This is, very possibly, the hardest thing in the process of getting testing going. As it ages, code base tends to gather patterns in both code and work habits. The longer the code base has been alive, the deeper these habits and patterns become ingrained in the hearts and minds of the team.
In this case, the code base in question has been alive for 30+ years. YEARS. This means that it has served the needs of the company for that long (even if it hasn’t done that so well on occasion). It also means there is lots of entrenched habits and knowledge in the engineers and management.
Changing the habits of the team and management will take a while. While the initial training was poorly planned by somebody who shall not be named but whose name sounds a bit like mine (*cough cough*) it may actually work in the benefit of the team in the long run. In recent days (at the time of writing), I have been able to get several team members to setup tests on the code they’ve been working on most recently. It is my hope that these folks will begin to champion testing once they’ve captured a few bugs before going to QA.
Testing a code base in many different ways (unit & integrations tests, QA automated & manual, user acceptance testing) is important to getting solid code out that matches what the users need. Writing tests on new code is easy if your team has the habits to support it and if timelines allow for it. Testing code has grown without tests is very difficult but it IS possible. Keep up the effort and get your team testing! As always, I recommend reading “Working Effectively With Legacy Code” by Michael Feathers for lots of information on the topic.
As always please reach out and let me know if you’ve got suggestions on how to make testing better or questions that I can help answer for you. Also, sign up to receive an email when I push out new posts. The sidebar has a sign up for and lets you choose what topics you’d like to hear about.