Thoughts for improving your business

What is agile? Get in touch

The Antibiotics of Software Engineering – Agile Testing


Surgery is not a recent invention, it dates back millennia. 

Notable Milestones in Surgical History (http://surgery.about.com/od/surgeryinthemedia/a/HistoryOfSurgeryTimeline.htm)

6,500 B.C.E. – Skulls found in France show signs of a rudimentary surgery called trepanation, which involves drilling a hole in the skull.
1540 C.E. – English barbers and surgeons unite to form The United Barber-Surgeons Company. These barber-surgeons performed tooth extractions and blood letting. Physicians were considered an entirely different profession, treating illness with medications.
1818 – First transfusion of human blood.
1843 – First hysterectomy performed, in England.
1843 – First use of ether.
1867 – British surgeon Joseph Lister publishes Antiseptic Principle in the Practice of Surgery, extolling the virtues of cleanliness in surgery. The mortality rate for surgical patients immediately falls.
1885 – First successful appendectomy performed, in Iowa.
1890s – Widespread use of chemical agents to minimize germs. Carbolic acid was put on incisions to minimize germs and decrease infection rates.
1896 – First successful heart surgery performed, in Germany. Surgeons repaired a stab wound in the muscle of the right ventricle.
1905 – First successful cornea transplant.
1917 – First documented plastic surgery performed, on a burned English sailor.
1928 – Antibiotics discovered.

Even if the procedure was successful, often the patient suffered and usually died of subsequent infections. 
Also, not to ignore is the discovery of Ingnaz Semmelweis, a physician at a Vienna hospital. While working at a Vienna hospital in 1847 he discovered that far more women died after childbirth by the so called childbed fever in the medical ward then in the midwifes ward. Semmelweis postulated the presence and spreading of germs causing the illness by doctors. Even though, after applying a chlorine and lemon based hand-wash solution the death rate could be reduced from ~35% to 1%, he was being labeled a heretic by the doctors. Ignaz Semmelweis was ignored until Louis Pasteur confirmed the germ theory.

Now, after it was accepted that germs caused infections and that hygiene was mandatory for good outcomes it became also obvious that there was a need to have a treatment once an infection set in. As listed above, on September 3rd  in 1928 Alexendar Flemming discovered the antibiotic effect of Penecillin and transformed medicine as we know it. Nowadays, antibiotics are used to treat all kinds of infections and antibiotics are prescribed in a preventive manner for many medical procedures. 

In software development we are able to develop rather fast and make significant changes to existing systems quickly. However, after these procedures the system often falls sick, suffering from bugs, side-effects and other ailments. I like to consider these as infections. Those infections even arise after well planned and executed engineering efforts.
The fundamental question is, how can we cope with them or even better avoid them – what is the the antibiotic equivalent in programming?
For me, the answer is: Agile Testing

Agile Testing is the process to validate that new functionality performs correctly and more importantly to verify that the existing behavior has not changed – that no infection has set in.

1. We have proof that the current system is healthy before the procedure starts
2. We are able to monitor the systems health during the procedure
3. We can intervene the moment side effects set in
4. We have proof that the procedure was successful 

A well done Agile Testing strategy is the equivalent to clean medical equipment and antibiotics. 

Most if-statements are evil

I’ve really come to loath if-statements. It developed over time. At the very beginning they are great as they give you the power to put some logic into you application. Usually a small program in one of your first programming classes. Well, over time I realized the hard way that they clutter your code and make it harder to read and hence understand and maintain. In OO languages you have far more powerful ways to put logic into your application without using if’s. However, this requires a good skill in programming and lots of practice. I’ve come to realize that you can identify a good programmer by her if-avoidance skill. Well, after some time in acceptance but dislike I now try to avoid them at any price and so should you. By the way, I consider switch-statements to be nested if’s.

Frederick Brooks coined once the terms ‘Essential Complexity’ and ‘Accidental Complexity’. The first describes the real complexity which comes from the domain and the problem to solve. The second one is manmade i.e. it is the complexity we get into by our own making like which OS, which language, which framework, … we choose. Using this point of view, there are essential if-statements and accidental if-statements. The accidental ones, what a fitting name, are the ones which need to be eliminated.

Essential if’s
There are things you need to check. Can I save the file, is there enough free disk space.
if (diskHasEngoughFreeSpace()) {
document.save();
}
hose decision are driven from external forces and are out of our control and so we need to check them every time we save.

Accidental if’s
Those buggers creep up everywhere in you code.
if (date == null) {
date = new Date(); // this is called defensive programming, one of the worst things you can do
}
[/code
or

if (date != null) {
uiWidget.setText(date.toString());
} else {
uiWidget.setText(“”);
}
Before you get creative in finding a workaround you should analyze whether date actually can be null. If yes, how? Is it a field of the class, a parameter of the method, a return value from a called method. All these questions and their answers provide you with a multitude of options.
/**
* @param date of the document to be printed; must not be null
*/
public void printHeader(Date date) {
// Usually I put those checks into a utility class and a checkParam method.
// i.e. Check.checkNotNull(date, “date”);
if (date == null) throw new IllegalArgumentException(“invalid parameter: date cannot be null. Good bye!”);

// once we are here we know that all parameter are valid
date.doSomething();
…
}
It is a good practice to have an object to be in well pre-defined state after creation.
class DocumentPrinter {
private Date date; // this is the same as private Date date = null;
…
}
It is better to do it this way
class DocumentPrinter {
private Date date = Date();
// if this is not sufficient then have  the date passed in as parameter with the constructor and make the default constructor private
…
}
or even better use the Null-Object pattern
class Document Printer {
private Date date = new NullDate();
…
}

class NullDate extends Date {
public void toString() {
return “not set”;
}
From now on you can use date anywhere in your class without the need to check for null.
Now lets look at a return value from a called method. First I would study the documentation of the method and see whether the method actually can return null objects. In important cases I would even go so far as to quickly write a bunch of tests. With those tests you have clear documentation if the method can return null and under which conditions.
public void doSometing() {
…
Date date = getDateOfTransaction(transaction);
…
}
Knowing, that date might be null we need to see how the variable is being used subsequently. If it is being used for some simple display purposes we can wrap the method and return a NullDate in case the return value is null. If there is some more serious work with the object down the road then ‘Houston we have a problem’! Creating a fake date will not work and invite some big risks. Bypassing the date accesses even more so:
…
doThis();
doThat();

if (date != null) {
rebate = calculateRebate(date);
bookTransaction(rebate);
}
…
Sure, we could move the bookTransaction-method out of the block and guarantee that it will be always booked. But, assuming that we are dealing with a preferred customer who always gets a 10% discount. In this case we will get bunch of calls to our customer service folks which would have to deal with an upset customer. We don’t want that. Depending on whether you have access to the source code of used method you can go in fix the problem if not then you have a problem which you should encapsulate. The encapsulated problem offers a clear separation between working and broken smelly workaround code. Also it adds a lot the readability of the source code and you would have only one place to go and do the fix.

But now let’s look at another piece of code. Assuming we have so transmit data via a selectable protocol. The transmission must be encrypted under specific circumstances. So the code could look like this
if (encryption.equals(“RSA128”)) {
encryption = new RSA128();
sendText = encryption.encrypt(text);
} else if (encryption.equals(“RSA1024”)) {
encryption = new RSA128();
sendText = encryption.encrypt(text);
} else { // no encryption
sendText = text;
}

if (transimission.equals(“ftp”)) {
FTPTransmitter transmitter = new FTPTransmitter();
transmitter.transmit(sendText);
} else if (transmission.equals(“ssh”)) {
SSHTransmitter transmitter = new SSHTransmitter();
transmitter.transmit(sendText);
}
}
How about this public void send(String text, String transmission, String encryption) { Transmitter transmitter = Factory.createTransmitter(transmission, encryption); Transmitter.transmit(text); } TransmitterEncryptionStrategy

First, we extracted a Transmitter interface or if feasible an abstract class. The transmitter internally uses a strategy pattern to encrypt the text. The encryption is injected during construction time of the Transmitter. Again, there is an abstraction for the encryption. The factory could be a own creation or you could use a framework like Spring.
class Factory {
public static Transmitter createTransmitter(String transmission, String encryption) {
Encryption encryptionObj = createEncryption(encryption);
return createTransmitter(transmission, encryptionObbj);
}

public static Transmitter createTransmitter(String transmission, Encryption encryption) {
Transmitter transmitter = createTransmitter(transmission);

transmitter.setEncryption(encryption);
return transmitter;
}
…
}
Sure, if you were following correctly I would expect a ‘but now we have the if-statements in the conveniently not shown createEnryption and createTransmitter method’. Yes, your are right. However, I consider those if-statements at this location to be essential. Also, if you use Spring the condition checking will be externalized into the bean descriptor file.
Also, since the factory is driven by Strings, these could easily come from the UI. In that regard the UI would drive the behaviour without adding any conditional checking and would be easily extendable to other means of transmission and encryption without the need to modify it. And yes, the code will much easier to test. MockObjects anyone 😉

PS If anyone can give a me hint to how show source code in a nice and readable using Blogger. This would be highly appreciated.