Do your customers keep complaining about bugs in your software application? Does it take you too much time to implement new features?
If you answered yes, then you probably have issues with the quality of your software application. Here are 6 practical steps that you could follow, to improve its quality.
Stop creating new quality issues
No matter what happened in the past, you are now responsible for not introducing any new quality issues with the source code that you write.
Step #1: Install SonarLint
As a developer, install SonarLint in your favorite IDE (e.g. Eclipse), and you will be amazed to find out that it will be identifying quality issues in your code while you are typing, giving you detailed instructions on what exactly you have done wrong, as well as what would be the proper way of fixing it.
Personally, I have been using SonarLint for the past year, and I discovered that it has helped me become a better software developer, by pointing out errors in my code that I was not aware of.
Step #2: Setup quality gates in SonarQube
As a development team, it is suggested that you enforce a quality policy, by establishing an automated way of checking every commit for quality issues in your source code, preventing any issues from being merged to the main line. In particular, you may configure Quality Gates in SonarQube, setting one or more thresholds for different types of quality issues. For example, you may require that submitted source code should not introduce any new critical or major issues.
Where do you spend most of your time?
As a developer, chances are that you spend most of your time reading code, trying to understand what it does. How many times have you read the same code, while trying to fix a bug or implement a new feature? Sure, you thought that this code needs to be refactored to be made more readable, but where do you start refactoring when you have a software application that is made up of thousands files (e.g. Java classes)?
Even if your application consists of thousands files, it usually happens that most of your software development activity is focused on a limited set of files. For example, in an enterprise application that I have been maintaining, I discovered that out of 10.000 files of source code, most of our development activity was concentrated on 10+ files, which would be changed in almost every commit.
Step #3: Refactor frequently changing files
It’s time to check your own codebase for the most frequently changing files, therefore implicitly identifying where you spend most of your time as a developer. If you have git as your version control system, then you may execute the following command:
git log --format=format: --name-only | egrep -v '^$' | sort | uniq -c | sort -r > files_change_frequency.txt
This command will print a list of sorted files from your codebase, with the most frequently changing ones (i.e. having the highest number of commits) being displayed first, as shown below:
Commits File 230 gr/kolaxis/Utils.java 220 gr/kolaxis/UserManagement.java 210 gr/kolaxis/UserTemplates.java
As a development team, you can now rely on actual data (coming from your version control system) to take a well-informed decision on which files need to be refactored.
Refactor the most frequently changing files in your codebase, by making them easier to be read, and understood by every developer. This is a refactoring effort wisely invested, which will enable every developer to spend less time reading code, therefore effectively helping your development team to become more productive.
Step #4: Focus your tests on frequently changing code
Do not waste your time testing mature code, meaning code that has not changed for a long time. Instead, focus your quality assurance efforts on testing frequently changing code, which is more likely to fail! The latter code is changing all the time either because:
- it contains quite a few defects, resulting in numerous patches in this area, or
- the corresponding features are popular to customers, resulting in numerous enhancement requests being implemented in this area.
Save valuable time by adapting your test suites to test only frequently changing code. As a developer, here is the question that you need to keep asking yourself: “What is the code coverage of our frequently changing code?”
Step #5: Do not touch old code!
When you open a source file that has not changed for a long time, resist the temptation to refactor it, no matter how “ugly” the code might be! Old source code has already withstood the test of time, having been running in production without any problems. Why should you invest any development effort in changing mature code that is proven to work successfully?
I have personally found out that fixing old code may introduce defects that I have not thought of. Therefore, if your old code ain’t broken, don’t fix it! Only exception to the rule is the case of “dead code”; that is code that was committed sometime in the past (during the development of a feature), but was never used. If you are certain that a piece of code is not called, then go ahead and delete it! Deleting “dead code” will make it easier for every developer to navigate through the codebase, and will also reduce the total build time of your software application, thus saving valuable time from your development team.
Who is touching your code?
How many developers are touching the code of a given component in your software application?
If you have many developers that have occasionally contributed source code, with only a few commits by each one of them, then it is likely that this component will suffer from quality issues. According to a research conducted by Microsoft: “The number of minor contributors has a strong positive relationship with both pre- and post-release failures …” where a minor contributor is a developer with less than 5% commits in a component.
On the other hand, if you have a single developer who has performed most of the commits in the component (also referred to as the owner of the component), then it is expected that the quality will be better. As stated by Microsoft in the same research: “Higher levels of ownership for the top contributor to a component results in fewer failures when controlling for the same metrics, but the effect is smaller than the number of minor contributors”.
Step #6: Pay attention to minor contributors
From all the components that make up your application, identify the ones with the largest numbers of minor contributors (developers with less than 5% commits). As explained previously, the more minor contributors you have in a component, the more defects are expected. For this reason, you will need to focus your testing on the components with the highest numbers of minor contributors.
As a major contributor of a component, you should be paying more attention when reviewing code submitted by minor contributors.
As a minor contributor of a component, you should always be consulting a major contributor (ideally its owner) before making any changes to it.
Interested to find out more?
Watch my presentation for an in-depth analysis of how you can improve the quality of your application:
If you prefer reading, the following resources are recommended:
- A. Tornhill, “Software Design X-Rays – Fix Technical Debt with Behavioral Code Analysis”, The Pragmatic Programmers, 2017.
- M. Feathers, “Working Effectively with Legacy Code”, Pearson, 2004.
- N. Nagappan, B. Murphy, and V.R. Basili, “The Influence of Organizational Structure on Software Quality: An Empirical Case Study“, ACM, 2008.
- C.Bird, N. Nagappan, B. Murphy, H. Gall, and P. Devanbu, “Don’t Touch My Code! Examining the Effects of Code Ownership on Software Quality“, ACM, 2011.