From debugging to quality

This article is part 2 of the debugging series. You can read part 1 here.

As we mention in part 1, debugging it's a complex specialty that demand specific knowledge and skills. In this section we will extend on debugging mentioning other scenarios and the positive things we can get from it.

"Even good programmers make mistakes. The difference between a good programmer and a bad programmer is that the good programmer uses tests to detect his mistakes as soon as possible." phpunit.de

The sooner the better

Debugging it's expensive and the later in the development stage the more expensive it becomes

Bad coding also increase the cost of testing, recoding, re-testing and badly damages the image of a developer/company. So try to test and debug code right WHILE WRITING it.

"The sooner you test for a mistake the greater your chance of finding it and the less it will cost to find and fix. This explains why leaving testing until just before releasing software is so problematic. Most errors do not get caught at all, and the cost of fixing the ones you do catch is so high that you have to perform triage with the errors because you just cannot afford to fix them all." phpunit.de

Here's a raw estimations about cost increase:

"Common rule of thumb (for waterfall) is exponential for each stage, so if a bug costs your group $1 to fix during the specification phase:

$10 in Design phase

$100 in working code

$1,000 in released software"

"Agile teams use the term 'velocity' to describe the estimated amount of customer value they can deliver per iteration. If there is still work left to be done, you are effectively lying to your customer about how fast you can deliver value. Since your customer thinks you can deliver more than you really can, you will be overloaded with work again next time. You will start accumulating technical debt." Ryan Coper

So make sure all code you produce is as clean as possible, do some testing, and if you identify some possibilities of failure / problematic exceptions, invest some times in creating a testing procedure

Recurring bugs

Some applications show recurring bugs, here are some possible causes for them:

    • Copy/Paste coding

    • Double coding

    • Bug is re-introduced by new changes

    • Incorrect fix

    • Partial fix/testing

    • Data related

Copy / Paste coding

A bad programming practice, where similar or identical functionality is simply copy/pasted from one place to another, this make maintenance difficult and force to maintain the same code in many different places.

When coding:

Avoid copy/pasting

Place code in classes or functions where it can be accessed system-wide

    • Model

    • View_strategies

When debugging:

If you discover the same code has been used in different places you will need to re-factor the code

    • Extract the code to a function and place in a class/function that can be accessed system-wide

    • Comment all sections of code that seems to be the same

    • Call the new function from all this places

    • Test each modified section of code extensively

Double coding

Some times it's even worse, developers not only copy/paste the code, but fully develop 2 different versions to perform the same task, this cases will normally evidence:

    • Lack of communications,

    • Bad planning,

    • Incorrect architecture

    • Neglecting/lazy developers

    • Lack of common resources definition

In this cases refactoring it's also required,

    • If not already in a function/class extract the code to one

    • Try removing the 'less mature' version of code or make an integrated function

    • Replace all suspecting versions and make call to the common function

    • Publish/Write down all affected places for the rest of the team to know

    • If there was a duplicated function try:

      • Remove 1 function version if possible

      • Replace all calls to this function for the new one

      • If impossible, make an empty function that calls the unified function

Bug is reintroduced by new changes

Some times developers reproduce a bug when fixing a new problem, this could be caused by:

    • Lack of care

    • Lack of information

    • Lack of clarity

To prevent this problems you can try:

Add Comments

The more detailed information the better, every time you fix a bug, add detailed comments (author, date, purpose)

Use versioning

At least you will be able to easily retrieve the old working version and compare to fix the bug

Create a test

Some cases are really difficult or obscure to understand, add your comments and create a good test that helps avoid bug reintroduction

Re factor

You can also try, breaking up the complex function/class into others, divide or specialize some cases.

Incorrect fix

Many times bugs are simply not fixed, this normally denotes a communication issue, if this case appears continuously:

    • Request a test case procedure,

    • Request/Code an automated test,

    • Request the "how to reproduce/expected result" section in the bug report

Partial Fixing

Other times the bug is just fixed for some specific cases, this can happen in complex functions where it's hard to follow the result of the execution.

Try:

    1. Bug report must include how to reproduce the error

    2. Check the code for splits and try to test at least one case for each path the code can take

    3. Create a test Unit for each different case detected in the previous step

    4. Request the test cases from your manager if they are available

* If not enough time is assigned for debugging, raise an issue to your manager explaining the need to invest time in creating tests for the specific case

Data related

Several times when systems are released for testing / using, data related bugs start popping up, this bugs should normally be avoided by defining a proper set of tests since the planning of the system, but it's mostly not done as it's expensive or the cases are unclear for the users.

When you find issues/bugs related to data, it's the reponsiblity of a good programmer to:

Clean the conflicting data

Normally when this errors occur is necessary to remove the dirty data or to 'clean/fix/ it

Prevent occurrences of the same issue

It's important to determine how data got corrupted and to implement/suggest measures to avoid future problems, this can include:

    • Client side validations

    • Server side validations

    • Modification of business rules

    • Closing some use possibilities/cases that can create a problem

    • Restrict access to some users to the possible place of conflict

Document the causes / solutions for this issue

Once the cause of the data corruption has been established

    • Create a document / report explaining where the data problem occur and why

    • Document the code where the solution can be implemented, or where other developers might be assigned in other stages to look for the same solution

    • Document how to clean/remove the corrupted data

    • You can also create a maintenance function to automate the cleaning of corrupted data (try to keep this function secret from standard users and fully secured so incorrect usage of the system doesn't become a practice)

Raise an issue when training to personal might be done to prevent the issue

(Some times customers don't allow the fixes to be implemented)

Some times customers doesn't allow to code the improvements required to prevent data corruption (very few cases but can happen). In this case a training program should be recommended on practices to avoid the issue to happen.

Refactoring

"Code refactoring is the process of changing a computer program's internal structure without modifying its external functional behavior or existing functionality, in order to improve internal quality attributes of the software, for example to improve code readability, to simplify code structure, to change code to adhere to a given programming paradigm, to improve maintainability, to improve performance, or to improve" Wikipedia

There are dozens of techniques for refactoring code, you can find an impressive list in this site maintained by Martin Fowler all with nice diagrams

http://www.refactoring.com/catalog/index.html

Planning and Writing tests

You can implement PHPUnit or another testing framework depending on the language you are using for development. If it's not in your hands to implement, try writing your own testing procedures. You can simply create a special class/screen to run all your cases and report results.

Check information on phpUnit site: http://www.phpunit.de/manual/3.4/en/writing-tests-for-phpunit.html

Read here a lot more about all the kind of testing that can be done

Bibliography

http://on-agile.blogspot.com/2006/12/hidden-cost-of-delaying-bug-fixes.html

http://on-agile.blogspot.com/2007/04/why-you-wont-fix-it-later.html