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:
Bug report must include how to reproduce the error
Check the code for splits and try to test at least one case for each path the code can take
Create a test Unit for each different case detected in the previous step
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