What to test your code change against

Posted by Kenneth Selin on October 5th, 2010

In this blog entry, I’m gonna discuss how how big part of the rest of the system/application you need to integrate in your test, before checking in your code.

We have all heard how much more expensive it gets when a fault is found at a later stage of the test chain (or even in a production system). It is a fact that software companies of any notable size does use several test stages. What these stages are called and how many they are, varies from company to company. The first test stage however is the test the developer is supposed to perform before checking in the code. This might be called “unit test” or “basic test” for example. Then there is typically an integration test, where it is tested that several modules delivered independently are able to talk to each other. At the next test stage, maybe called “function test”, it could be tested that the system’s functionality works. Another test stage could test non-functional requirements, like stability and performance.

The further down the test chain, the closer to the real production environment we get. Real database management systems are used (I call these “databases” from now on), expensive hardware, and so on.

And again, if a bug is found late in the test chain, it is usually more expensive to fix, since you might want to pass all the test stages again. This could make you feel guilty as a developer, when a bug is found, and maybe lead to pretty strange behaviour to avoid finding the bugs “late”.

There are many examples of companies where the developers are supposed to test in production like environments, with real databases, expensive hardware and so on before checking in the code. It is easy to understand that this kind of testing takes a lot of time, and is typically performed manually.

All these test stages and the company culture revolving around the test stages can be very confusing. What is a developer actually supposed to do before checking in the code?

The developer needs to test the changed code towards it’s interfaces until the developer is confident the change works.

This statement holds a lot in it, so let me elaborate.

First we consider that the code must be tested towards its interfaces (for example other classes, protocols, etc). Here, it helps a lot if the interfaces are clearly understood. If you know (by documentation or experience) what the interfaces used by the code return, you can much faster get confident that the change works, by somehow getting the interface to return the values you need for your test. Now, you should preferrably mock the interface in an automated test case, which will let you get confident of your code change very quickly.

Understand that as long as you get the interface to return the values you like, it does not matter where the values originate from. A String is a String, regardless if you mock it into your stubs or if you dig it up from a database in some layer far below yours.

That is, it does not add value to the test if you dig up the string from the database, it just takes more time and money.

A recurring statement from people prefering to test (manually) using real databases is that “they want to be sure that it works”. This is in a sense a good ambition. They want to do a good job for their employer, and not get blamed later. However, time and money are critical resources for the employer, and time and money must be spent right. If you can test quickly and cheaply, getting you confident that the change works, you should do it. At odd times, a bug you could have found using (manual) database-based test might slip to later test stages, but this means 1) you did not understand the interfaces and/or 2) you were sloppy while testing.

Testing faster and cheaper frees up time and money for the employer, making the developers more productive.

Sometimes however, you might not be able to get confident of the test using just stubs. This is when the interface is not well understood, since it is not well documented or for some reason can not be trusted. Also, if you are new to the code base, it is harder (and should be harder) to get confident. In this case it might be fine to test using real databases (if not anything else, it will teach you more about how the real system functions), but it could be smarter try understanding the interface instead and then test the code change using stubs.

To sum it up, it is a waste of time and resources to integrate a lot of “real” software (like databases) into your test, and you should not do it routinely.

(The topic of manual versus automated testing is maybe for some other time :) )

How to write an error message

Posted by Kenneth Selin on September 16th, 2010

When you run someone else’s software, there are sometimes error messages which are hard to understand. Most likely, you will always understand error messages from your own software, not necessarily since the error message is good, but since you wrote the code for the software, you will know much about the conditions when it is reported.

It is very annoying to stumble upon a bad error message, for two reasons: 1) the error message does not help you analyse the problem, 2) you realise that phrasing a better error message would probably been very easy for the developer, but she ignored it.

The hard and fast rule for error message is: the message needs to be specific, and using the language of the reader.

Examples of implications:

You need to tell which file you could not open. Stating something like “failed to open file” or including a stack trace with FileNotFoundException is bad.

Stack traces are in general bad, confusing and, all too often, lengthy. If an exception is thrown all the way up to the highest architectural level and you at this point don”t have more information than the instance of the exception and the strack trace, something is wrong, for example a bug in your or in a library’s code. At this point, you have to log what you know, and then finding a fix for your bug or your unhandled configuration problem.

Mini-review of Clean Code

Posted by Kenneth Selin on August 29th, 2010

This summer I borrowed the book “Clean Code” from the office (author: Robert C. Martin).

I write this from memory, without cheating and opening the book again.

As the title suggests, it’s about how to write “clean code”, and what this is, is discussed in the beginning of the book. The rule of thumb that I liked, is that clean code looks “pretty much as you expect it”. That is, when you look at someone else’s code and it doesn’t surprise you with ugliness, it is actually clean! I have myself experienced this when I looked (just a little) an the Java SDK source code. I was like “yeah good code, nothing special to it”. But this means that it is clean.

All in all, I really liked this book, much for its great ability to inspire. An experienced developer will have heard about quite a lot of the contents, but probably not all, and together it is a very inspiring  read.

My favorite part is the discussion of 2 of the parts of the SOLID design principles, namely Single Responsibility and Open Closed Principle.

As I feel it, Single Responsibility Principle will take the design of your application very far if you are able to apply it. The rule basically says “A class (or other program entity) shall have just one responsibility, i.e. one reason to change.” The advantages of this are quite obvious: such a class will have a greater chance of being reused since it has a more clean purpose, and it will be easier to maintain, since this class has (by definition) just one reason to change, so you can’t mess anything else up, while you modify it!

The SOLID design principle I think is second best, is “Open/Closed Principle”, meaning the system shall be “open for extension but closed for modification”. If you are able to apply this, you will find that you can add classes and stuff when implementing new functionality, rather than modifying existing code. Again, there is a smaller risk you mess up the existing functionality.

The book contains numerous thoughts and tips and tricks about how to make your code cleaner, for example:

  • A function shall not do stuff on different levels of abstraction.
  • Various patters you can return to if you find your code being ugly, for example if you think exception handling takes to much focus from the reader.

A great read!

Builder Pattern

Posted by Kenneth Selin on August 20th, 2010

I stumbled on a very cute design pattern the other day, and I’d like to share it.

It’s supposed to be used when a Factory doesn’t provide enough flexibility, since the creator of the object wants to control also how many properties to set on the created object.

One of the reasons I liked this pattern is since it can provide so much readability to the code. I spent a few minutes trying to find the example I read the other week, but I couldn’t find it again. Those examples I found on the web this time did not use the readability enhancements, but they were still of course examples of the Builder pattern.

A Builder is a class able to construct another object, much like a Factory.

The feature that I think provided the readability, is that methods are called “withX” and return “this”, which means that it’s possible to repeatedly invoke “withX” methods.

This is how cute it gets:

Car.Builder carBuilder = new Car.Builder();
Car car = carBuilder.withTires(4).
                                           withColor(Car.Red)).
                                           withCylinders(8).
                                           withHorsePower(1000).
                                           build();

In this example, Car.Builder is the Builder class, able to construct Car objects.  How explicit this code is! It’s easy to see that “8″ means “number of cylinders” and so on.

One idea behind the Builder pattern is also that it is able to provide convenience methods for recurring groups of attributes. Let’s assume a Car with 8 cylinders and horse power 1000, is a “sports car engine”. Then the Builder class can provide a method for just this, and the code would loook like:

Car.Builder carBuilder = new Car.Builder();
Car car = carBuilder.withTires(4).
                                           withColor(Car.Red)).
                                           withSportCarEngine().
                                           build();

The build() method returns the Car that was constructed, and may also contain consistency checks, i.e. that the set of properties set was appropriate.


Copyright © 2010 NullReference. Web hosting.