For every project, no matter the size, it pays off to fix bugs and take code quality serious.
For private projects on Github, it shows colleagues and potential employers that you are invested in high-quality standards — A big plus over your competition.
Small to medium size products might have a smaller but very loyal user base. Giving those users the best possible quality will keep them loyal and turn them into missionaries for your brand.
Large Products with thousands or millions of users, where a 0.1 percent change in conversion rates might cost millions of dollars a day due to bugs in their systems.
So, fighting bugs is always important and there is no reason why you should not do it.
But sometimes, as things get a bit more complex, we need to have a strategy to fight bugs. This guide is not the “One Size Fits All” manual for zero bugs, but it gives you a starting point.
The first step is to have a plan
Having a clear plan helps a lot when it comes to achieving a specific goal. Agile Teams spend a portion of their time with planing because they know that a good plan saves more time than it takes. Those plans often include an estimation of the effort to execute a plan, especially when it comes to the development of new features. On the other side, it’s very difficult to estimate how long it takes to fix a bug — more often it’s just impossible to give a reasonable estimation.
Who knows why this spooky application state occurs for some users and not for others?
When you start investigating the underlying issue it might take a couple of minutes or weeks to get to the bottom of a bug.
To make a plan for fixing bugs and improving code quality start with a fixed 30 days timeframe and work your way down that timeline. You will not fix all bugs or improve everything there is, but you are 30 days closer to getting it done.
Getting Things Done
Great, your team has decided to improve the code quality and reduce the number of bugs in your product. Here is how you can act on this commitment.
Freeze feature development
If possible, stop the development of new features. You can’t be sure that no new bugs come up while fixing the old ones. Instead treat the next 30 days as a special event for the entire team, much like “project weeks” back in school. Use the beginning of this week to get everyone in the right mood and highly motivated to fix the code. Make sure that it is fun to make things better and not bone-crushing, long-hours, weekend killing work!
Create a user journey
The user journey is a very important part of your entire product organization. If you don’t already have a comprehensive user journey, sit together with all people across your product organization and identify the single most important journey and write it down. Focus on completing the user journey documents at a later point. When you already have a completed user journey, identify one branch that is both related to the code base, that you are about to improve and mission-critical for your team.
Check and evaluate your current code coverage.
This tells you where the most untested code is so you get an idea where potential bugs are. A low coverage doesn’t mean that there are bugs, it just shows where you lack certainty about the correctness of the code. The more critical this untested part of your application is, the more you should focus on those parts during the next days.
Log your errors
Every time a users runs into an error or the browser throws errors in the console you should log the error somewhere. Sentry is a great service for that purpose. They ask for a small fee which is very reasonable in my opinion and also offer a 14-days trial. If you cannot or don’t want to use the managed service, you can still use the OpenSource self-hosted version. Deploy an initial version to your users so you will collect insights during the next weeks that you can compare with future data.
Don’t rush through the first week! Take your time and learn everything there is to know about your code quality, bugs, and errors that your users run into. The user journey is vital for this project and the future. Consider making a workshop with as many product people you can. Finally, discuss and make a plan for your next move before you act.
Write tests. Not too many. Mostly integration.
This is a quote from the developer and writer Guillermo Rauch. It is the best summary of any testing strategy and I can’t come up with anything better.
End-To-End tests and integration tests
Focus on getting a testing framework up and running and start with simple tests for the critical parts of your user journey. Don’t worry about testing against every browser and environment there is. Keep it simple and just test against one browser. Puppeteer is a great choice to automate a Chrome browser and write your first end-to-end tests.
Given a user journey that says „A user sees a call to action on the homepage that shows him a login dialog when it‘s clicked“.
A test should not cover any implementation details like Whats the class name of the button, instead, it should test if the journey works.
A test as simple as this is a good start:
1. Go to the / page
2. Find a button that says „Login Now“
3. Click that button
4. Expect to find an input element of type „password“ on the page
If this test passes, you just gained confidence that clicking on a „Login Now“ link presents the user a login form. It might be inside a pop-up or a new page, its not that important because you will add more test later that will cover more details.
Use the same strategy for more parts of your critical user journey and add some more detailed tests for each part.
While you work through the critical user journey paths you might encounter known or previously unknown bugs. This is the perfect time to write a regression test.
Imagine you work on a messaging application. When users type longer messages they might want to use the Enter key to create a new paragraph inside the message. Instead of adding a new line, the message will immediately send when you hit Enter.
Most likely this will annoy your users and lead to some unfinished messages and frustration.
A proper regression test would be:
1. Find and focus the textarea with the label „New message“
2. Type „Hello friend,“
3. Hit *Enter* key
4. Type „how are you?“
5. Expect the contents of the textarea to be „Hello friend,\nhow are you?“
6. Expect current focus of the browser to be the textarea
This regression test describes the behavior of the application as it should be, not how it is. When you run that test make sure that it fails.
Resist the temptation to fix that bug right now. You will take care of that in the next week. Now that bug is documented with a test and can‘t be forgotten in the future.
Take your time during that week to write reasonable and good tests for your application. It’s ok to write more regression tests then you can fix during next week. The important part is that you documented bugs with a test.
At this point, you will have a couple of important end-to-end test and probably some regression test. These tests ensure that the tested parts of your application work as intended and that known bugs are properly documented.
You can safely start refactoring now. If you accidentally break something your tests will turn from GREEN to RED as an indicator that something went wrong. The same is true when you fix the bugs. When a regression test turns from RED to GREEN you have confidence that your fix works and that it doesn’t break other parts of your application.
When you refactor components, add Unit Tests while you extract small isolated units of code. These test typically execute very fast and are less complex then end-to-end tests or integration tests. If you plan to introduce a new function to abstract common logic — start with a unit test and implement the function afterward. If you do so, you are now actively doing TDD (Test Driven Development).
Use the final week to finish and polish some tests and bugfixes. Don‘t start something completely new.
You might already have some kind of automated build and deployment scripts. In the case of a front-end project, it might involve installing dependencies, preprocessing the code and creating a bundle which will be deployed to some sort of hosting provider — Netlify, AWS or Azure to name a few.
Work on adapting your build scripts to run all test except the end-to-end test before you publish the new code to your users. If a test breaks, the build should fail. This ensures that someone looks into the error messages and no broken version will be released to your users.
When everything passes and the new code is successfully deployed. Run all your end-to-end tests against the production environment. Local, development and production environments are not the same and it’s important that your test makes sure that everything works for your users — not for your development team or quality assurance tester.
You might do some extra configuration of your test to account for different environments. For example, testing a login form requires a different API endpoint with a different user account.
Take your time and develop a system that allows you to run your tests against different environments.
The entire team committed to creating better software with fewer bugs and that alone is a huge achievement. Also, you gained certainty that critical parts of your user journey are working as expected and bugs that you fixed will never bother your users again.
In a Post-Mortem, you should discuss the past 30 days and express what worked well and what did not.
Testing your Software is something that you should do every day and every time you write code. Apply the techniques that you‘ve learned to your everyday work to constantly improve step by step.
Developing software with high quality needs practice and experience, but once you get familiar with testing strategies and tools it will greatly improve your entire product organization.
From my experience some positives effects are:
- Faster release cycles
- Fewer bugs
- Less customer support requests
- Higher conversion rates
- Less stressful extra hours
- Better onboarding for new developers
- Happy customers
Have you ever made a special Testing and Code Quality event with your team? If so, how was your experience? Let’s discuss in the comments.