We often inherit existing Django projects at Lincoln Loop either to provide ongoing maintenance or build new features (or both). Usually these projects are in some state of neglect and disrepair when they come to us. If they were a house, they might be on the verge of being condemned and require some urgent repairs to prevent a catastrophe.
To make matters worse, the tests are usually non-existent or broken to start with. So how do you make changes and have some level of confidence that you aren’t breaking other things in the process?
Writing a complete test suite from scratch would be a large (expensive) undertaking and one that would not deliver much in terms of immediate value. We use smoke tests.
Smoke tests give you the maximum coverage with the minimum effort. Pick out the key views or API endpoints and test that they return a 200 status code. Got something that requires a login? Verify it returns a 302, 401, or similar.
Here are a few examples of smoke tests in Django (also using the wonderful model-bakery library):
Are these tests perfect? Definitely not. Lots can go wrong that these tests won’t catch.
Are they better than nothing? Absolutely! They will exercise large swaths of code and will catch show-stopper bugs that otherwise might go undetected.
With smoke tests we can move a little more confidently in a foreign codebase, allowing us to fix the most egregious problems
What’s Next
We want to work on improving tests and coverage over time while still delivering immediate business value to the client throughout the process.
We need to know if our fledgling tests are passing (and not just on the developer’s laptop), so if there’s no CI, we will get something basic going there. Usually in GitHub Actions or AppPack.
Then we start working with a “leave it better than you found it” philosophy. Need to fix a bug in an untested portion of the code? Deliver it with a test. Writing a new feature? Deliver it with a test.
Over time, both the quality and coverage of the test suite will improve and you’ll be able to rescue the project from condemnation.