Wednesday, January 15, 2014
The Antibiotics of Software Engineering - Agile Testing
Friday, August 7, 2009
Mock Objects In Action at the Agile 2009 conference
How can mock objects help you design your system better? Want to know how mocking saved hours of work? We focus on establishing best practices based on examples with mock objects. We cover design of classes, using mock objects to understand and test interaction between objects of the system. By the end of the session it should become clear how mocking, when applied correctly helps with system design, improves testability by reducing cost of change. An explicit part of this session is dedicated to the Mocking top offenders. We talk with examples about bad usage of Mocks, and its consequences.

Sudhindra Rao and I will be presenting the Mock Objects in Action session at the Agile 2009 conference.
History of this session
I started conducting a session on mocking and testing when we was coaching a few developers. That session then turned into a training session conducted at ThoughtWorks internal training and was quite appreciated for its practicality. After a few additions to that sessions and adding mockito to the mix Sudhindra and I presented it at a couple of conferences. It was received with a lot of enthusiasm.
Recommended readings
Below is the list of recommended readings that I give to the session attendees. Please let me know what you would add to this list.
http://martinfowler.com/articles/mocksArentStubs.html
http://xunitpatterns.com/Mock%20Object.html
http://developer-in-test.blogspot.com/
http://misko.hevery.com/code-reviewers-guide/
http://codebetter.com/blogs/jeremy.miller/archive/2006/01/10/136407.aspx
http://www.jmock.org/oopsla2004.pdf
The demo code for this session will be available at: http://code.google.com/p/mocksamples/
Monday, June 8, 2009
Most if-statements are evil
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();
}
Those 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
}
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
public void send(String text, String transmission, String encryption) {
String sendText = “”;
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);
}
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 ;)
Wednesday, November 19, 2008
Testing private methods, TDD and Test-Driven Refactoring
While being a TDD--Test Driven Development--coach, I am always asked about testing private methods. I finally decided to write about my experience on testing private methods.
When really doing TDD (i.e. writing the test code before writing the functional code, and then refactoring the code) private methods are guaranteed to be test covered. When driving the functional code design and implementation from the unit test (aka Test Driven Development), no method is created private. Instead, the private methods are extracted—extract method refactoring step--from a public or package level method. The Example 1 below presents a scenario on applying TDD and how the private method is created.
New code development following TDD
Example 1: new code development following TDD
Consider the development example following a TDD sequence for creating methodA and methodB.
- create testMethodA/ create methodA/ refactoring
- create testMethodB/ create methodB/ refactoring: extract methodC
On the first sequence, the testMethodA is created for validating the functionality expected of methodA. The methodA is successfully created: All tests including the testMethodA are passing. Then you look for improvements in the code; refactoring.
On the second sequence, the testMethodB is created for validating the functionality expected of methodB. The methodB is successfully created. All tests including the testMethodB are passing. Then you look for improvements in the code; refactoring.
While looking for improvements in the TDD Refactoring step, you recognize that methodA and methodB have a common fragment of code (code duplication). You extract the common code fragment into a private method whose name explains the purpose of the method--methodC. Then methodA and methodB invoke methodC.
In this example testMethodA covers methodA, which invokes private methodC; therefore the private methodC is test covered.
Please keep in mind that this is a simplified example. Your methods and tests should not read like testMethodA / methodA, and testMethodB / methodB. Jeff Patton describes how test cases can describe design in his Test-Driven Development Isn’t Testing paper.
When doing TDD, the private methods emerge from your code. And because you test-drive your development, no functionality is added without a test. So, for code fully developed by following TDD you won’t have to test the private method separately: Private methods are already being tested by previously written tests.
Improving legacy code following Test-Driven Refactoring
Test-Driven Refactoring
Test-Driven Refactoring is an evolutionary approach to improve legacy code which instructs you to have test-proven refactoring intent. Basically, you start by writing a passing test around the code to be improved, and then you refactor the code; improving its internals, yet still passing the test suite.
While doing Test Driven Refactoring, I am trying to perform small refactoring steps and, at times, I find myself attempting to test a private method. This typically happens when I am working on an existing code base with very low test coverage. And the public methods are too complex to write tests for.
Example 2: test driven refactoring for existing low test coverage codebase.
Consider that you want to improve the following code:
public void overstuffedMethodX(){
…
// very complex code
…
// invoke private method methodY()
someString = methodY();
…
}
private String methodY (){
…
}
In the scenario presented in Example 2, the public method does not have corresponding unit tests. And I don’t feel comfortable refactoring code which does not have tests around it. Therefore I will follow Test-Driven Refactoring for improving the code. Below I will explain two different approaches for doing Test-Driven Refactoring for improving the code in Example 2.
Top down Test-Driven Refactoring
First you create tests for the complex public method:
public void testOverstuffedMethodX(){…}
At this point there is test coverage around the overstuffedMethodX() functionality, so you are able to refactor the overstuffedMethodX() code, including refactoring for the private method methodY().
In the top down Test-Driven Refactoring approach, first the unit test for the public method is created, and then its internals (including the private methods) are refactored.
Let’s now look into another approach.
Bottom up Test-Driven Refactoring.
No test for the complex public method is created.
Instead you look for smaller pieces of improvement.
You change the access level for the private method to make it accessible from a unit test.
private String methodY (){}
becomes
String methodY (){} // package level access in Java
Then you write test for methodY()
public void testMethodY (){…}
Then you refactor methodY(), and verify that the improvement works as the testMethodY() test still passes.
In the bottom up Test-Driven Refactoring approach, you first improve the test coverage and the code for the private methods and the internals of the complex overloaded method. By doing so, the code becomes less complex; after that you can start moving up the chain, increasing and broaden the test coverage until you are able to take care of the public method.
When applying the bottom up Test-Driven Refactoring approach for Example 2, the private methodY() is made package level in order to be accessible by its corresponding unit test (consider the package access level for the Java language). Similarly to testMethodY(), other tests are added in a bottom up approach. After increasing the test coverage and improving the code internals, it becomes easier to create testOverstuffedMethodX(), and finally, refactor the overstuffed complex method.
Top down versus Bottom up Test-Driven Refactoring
Even I consider the top down approach to be more purist as it does not change the private methods access level, its implementation is not always straightforward. The public method might be almost “untestable” (e.g., static, dependencies, long, complex) in its current state. For such cases, a bottom-up approach might be more suitable. As I see it today, code refactoring activity is a combination of bottom-up and top-down approaches that enables you to have small proven steps towards a cleaner solution, which still keep the same interface (the external behavior which is verified by the test suite).
Bottom-line, while doing Test Driven Refactoring, I have provisionally added tests for the private methods. In Java, I deliberately remove the private namespace from the method declaration, changing the method access level to package access level. This way, the corresponding test class--located under the same package--can invoke the method and test it.
But I won’t stop the refactoring until I remove the test for the private methods. I have experienced two refactoring sequences which finish without explicit tests for private method.
In the first refactoring sequence, some later refactoring step moves the private method to a different class. Basically, you realize that the method’s functionality is beyond the original class’s purpose; you identify, create the new class, and move the method – which now is public access level.
In the second refactoring sequence, the method access level goes back to being private and you delete the test which was directly invoking it. Because of the increasing test coverage--as a result of the Test Driven Refactoring--new test scenarios are added for the public method which invokes the private method. Once you (perhaps assisted by test coverage and analysis tools) realize the extra test coverage on your private method, you perform my preferred refactoring step--unnecessary code deletion. The test for the private method can be safely deleted as its functionality is being tested by another test method.
Should I add test for private methods?
So, here is my answer to the test private method question: After successfully doing TDD or Test-Driven Refactoring, your code will not have specific tests for the private methods.
If you are developing new code, you are following TDD. You test-drive the development and no functionality is added without a test. Private methods are only created as the result of a refactoring step. And the path of code going through the private method is already being tested by previously written tests. So, after successfully doing TDD, your code will not have specific tests for the private methods.
If you are improving a legacy code, you should be following Test-Driven Refactoring. In this case, you may provisionally add tests for private methods. Gradually, with the increasing test coverage, the tests for the public methods will cover all the paths, including the paths going through the private methods. At this point, you don’t require the tests for private methods anymore. So, after successfully following Test-Driven Refactoring, your code will not have specific tests for the private methods.