Software quality: refactoring

According theory software quality isn’t negotiable and teams make all effort in order to adhere to defined quality standards that have been agreed upon and achieve best results from quality perspective. In such ideal environment, the Product Owner and other main project stakeholders understand the importance of quality, as it is part of the organizational culture.
But as we all know it is not always true, and it is because quality cost requires an extra effort. Low product quality can be a consequence of various reasons:

  • Lack of technical knowledge on a specific domain. Especially for new guys in the Team.
  • Insufficient (or no) unit test coverage.
  • Different coding style within one Team. Or too many standard violations if organization/team has coding standard.
  • Team has no automated building, regression testing, packaging and monitoring activities. Such Teams make all the work manually and as the result it leads to higher possibility of making “simple” mistakes.
  • Teams do not apply software design and programming principles as Single responsibility, Separation of Concerns or Open/Closed and etc. This leads to chaotic coding and increases number of cross dependencies.

In this case it is obvious that the Team doesn‘t actually perform as well as they should. Even though it takes time to get use to working like this, but it definitely worth it. But of course quality problems might occur not only due the Team performance, but:

  • Product Owner is forcing on delivering features – not quality
  • Contractual obligations or very big scope changes
  • Importance of time to market

I agree that sometimes we face situations that we need to make extra work (add a feature, scope change, early release and so on) to please our customers and as the result it might affect quality.

But there is one important thing to keep in mind – such situations must be exceptional. If it occurs very often the Team, Scum Master and Product Owner must have a very serious conversation to communicate following message – Software increments cannot be delivered successfully continuously sprint after sprint without proper focus on quality. And solutions must be found if you face problems mentioned above.

Pros for quality are very obvious:

  • You will not be able to guarantee product stability overtime
  • Introducing new features will take more time the longer you develop in a chaotic manner
  • You will face a lot of code cross dependencies which leads to hard to change code
  • Mysterious breaks will occur in your solution while developing something new
  • You will need to introduce patches more often and etc.

So, the first thing you need to do is to reserve time for quality in each sprint (all stakeholders must be convinced that this is important) and grab this book to read – Clean Code: A Handbook of Agile Software Craftsmanship. This book helps to understand the importance of quality.

Code refactoring must become part of the development process and it shouldn‘t be very difficult when you have high code coverage by unit tests. If you don‘t have them, start implementing some good unit tests for critical parts of your product, to make sure those work as desired. Reaching this milestone allows you to start working on refactoring with less risk to break anything.

Write a test, refactor, verify your change by running all your tests and check in the changes. Repeat this cycle over and over and try to avoid a big refactoring spending all sprint (or several, which IMHO is even worse) on improving the code since it doesn‘t bring any value to a client – keep things small and obvious. Big refactorings should be treated as redesign and requires a bit different approach and additional focus – discussion with architects, infrastructure changes and etc. So it shouldn‘t be a part of everyday development.

Conclusion: Take refactoring into account when estimating your work.

 

3 thoughts on “Software quality: refactoring”

  1. I agree on most parts.It's better to start with a test and then refactor the code. But sometimes source is very dirty and it's extremely hard (nearly impossible) to cover such code by unit tests. Then what?Imho, in such cases you have to do refactoring and then cover new code with unit tests. Anyway, to minimize risk, you should refactor it step-by-step by limiting refactoring works to as small part of code as possible at a time.

  2. QUOTE: "Imho, in such cases you have to do refactoring and then cover new code with unit tests."how are you going to make sure that old logic is "covered" and component works in the same manner as before implementation.so, i would treat unit tests written before refactoring as some kind of measure that everything works in the same way later. p.s. it could be not only unit tests of course, but f.ex. test cases or something else

  3. Simply covering new logic with unit tests will not ensure that it still works in the same way as before.But sometimes it's hardly possible to cover old code with unit tests (e.g. old code uses data directly from DB, part of logic resides in DB procedure, other part in application code, data in DB isn't constant). After refactoring you can compare outputs of old and new codes (using the same inputs) but sometimes even outputs can differ (e.g. when logic uses random number generator)

Comments are closed.