Why unit testing speeds up development

In the book Java Extreme Programming Cookbook , Eric M. Burke and Brian M. Coyner describe the top reasons why one should do unit testing and why. The book itself may be a bit dated, the  reasons described in it are still valid today.

- Tests Reduce Bugs in New Features

- Tests Reduce Bugs in Existing Features

- Tests Are Good Documentation

- Tests Reduce the Cost of Change

- Tests Improve Design

- Tests Allow Refactoring

- Tests Constrain Features

- Tests Defend Against Other Programmers

- Testing Is Fun

- Testing Forces You to Slow Down and Think

- Tests Reduce Fear

Testing Makes Development Faster

In this article i would like to focus on this last reason. For most developers this doesn’t seems logic and even for management people it seems a bit far fetched. So is this statement true?

Well for me the answer is not straightforward. It strongly depends on the context. In fact when i don’t have to work with other people I can produce clean good code fast with a limited set of unit tests. These unit tests are often not really unit tests but just sanity tests to verify that the system behaves like i want it to behave. Even when the system becomes bigger and bigger (+10.000 loc) I can still add functionality ‘s fairly easy,  I don’t miss unit tests. The reason why is because i know the system / codebase very well, hence i wrote it. So in this situation i would say that testing would only slow me down.

However, everything changes when you turn to enterprise applications. You’re no longer working alone and the code you write will outlive the time you’re working on the project. Suddenly you have to use code that isn’t your own, code that you often would like to change because it doesn’t do exactly what you want, but when you dive into the code you notice that the impact would be rather big so you don’t change, you just look for a work around. Sounds familiar?

When developping with no unit test i usually see 3 different phases where the development speed changes significantly

  1. Limited setup.
  2. When the frameworks you want to use are in place your starting to produce new features very fast.
  3. When the system becomes more complex or more developers start working on the project you’ll become less efficient because you’ll loose time undertanding & verifying the system.

When you are writing unit tests this curve becomes different (see the blue line). Your initial phase will demand more setup (you’ll need a test framework, datasets, a CI,..). When you start programming your loosing time creating unit tests. However in the third phase a bigger codebase or other developers won’t slow you down, you have your tests and their tests to prove the system works. Your productivity won’t drop over time as it would if you weren’t writing tests.

What if the codebase of the other person was provided with a substantial set of unit tests. A set that would say : “if all tests succeed, I guarantee that code still does what it should do” and if a tests fails it exactly shows you where some behavior is broken . This is great, i could change the code to add things I want without wandering if the code still does what it should do, i just run the guys tests and i have faith. This is a great world to be in as a software engineer. I noticed that i could advance way faster than if this software engineer wouldn’t have provided me with these tests.

I have “faith”.

This is probably the most important reason why unit tests speed up development in a enterprise context.

I can thrust that everything still works if all tests pass. If tests fail they will point out exactly where the problem lays.

However to be able to have this kind of faith you have to have a high unit test coverage and good unit tests. When these conditions are respected you’ll find yourself in a situation that the effort for adding new functionality ‘s is almost independent of the size of the application and that in the long run it will speed up development.

What’s a high unit test coverage? As starting point I usually say > 75%, things like exception handling and gui component positioning aren’t that crucial when it comes to unit testing. What about testing your domain objects or value objects or data transfer objects or…? Often people argue that these things (simple pojo’s or javabeans) shouldn’t be unittested because “it’s too simple to break” . I don’t completely argree with this statement, you should test it’s correctness but you should find an efficiant way of testing these things. More on that in a next blogpost.

Unitils 3.3

Hi All,

Unitils 3.3 has gone live.  With the new release we can introduce to you the new io moudule.  No more endlessly repeating the same code to read a file, or figuring out a temporary file. The new unitils module does this for you !

Just adding @FileContent or @TempFile and your good to go.

How to do this? Check the brand new tutorial right here : http://www.unitils.org/tutorial-io.html

As you notice on the tutorial the unitils site has got a brand new look! Fancy right? (http://www.unitils.org) (try ctrl-F5 if you still get the old look and feel)

Except from the new module and layout there are some fixes and some small feature request that are added.  You can find out more in the release notes :

Bug

  • [UNI-119] – Found more than one bean of type PlatformTransactionManager in the spring ApplicationContext for this class
  • [UNI-186] – DbUnit dataset loading fails with a NoSuchColumnException
  • [UNI-221] – Why assertReflectionEquals not compare Timestamp?

Improvement

  • [UNI-181] – Remove hibernate dependency of dbmaintainer and make dbunit an optional dependency

New Feature

  • [UNI-11] – Add utilities for creating and cleaning up files
  • [UNI-232] – EasyMockUnitils – Add reset() method
  • [UNI-235] – Add utilities for loading the content of a file

Next up will probably be the 4.0 release, but more on that later!

Any questions, remarks or congratulations can be left in the comments underneath!
thanks for reading and stay tuned!

Unitils IO Module Sneak Preview

Hi All,

We’re currently working on a new core module for unitils. This one should be released with the 3.3 release (planned for the end of october).

Your probably wondering whats the purpose of this ‘IO module’. Basicly the same as with most other modules, reduce the boilerplate code and make life easier for developers.

There are two main features in the new module.

  • Loading files into objects
  • Creating temporary files

Let’s start with loading files into objects. The basic example is  the content of a file in a String object. This should look like the following.

 @FileContent(location="org/unitils/examples/FileContentTestFile.txt")
 private String content

@FileContent
 private String defaultContent
 

The first part should be clear, Unitils will search for the given file on the classpath and puts it in the string.
But how about the second one? In the dbunit module we have a mechanism that searches for a default file. So we reused it. If you do not override the location the IO module will search for the file with the same path, same name but with the extension .txt (in case for strings). Its should also be possible to specify an encoding.

There will also be out of the box support for properties support. It works the same way. This time we’ll expect the extension ‘.properties’. So working with a property file should look something like this:

@FileContent(location="org/unitils/examples/somePropertieFile.properties")
private Properties defaultProperties

It ‘ll be possible to make your own converters of readers but more on that on the actual release!

The next feature the IO module will provide you is creating temporary files,this can be a real file or a directory. We ‘ll also try to remove the temp file at the end ! This code has not yet been written, So namings will probably change and extra features could be added. From our point of view it should look like this :

@TemporaryFile(Directory=true, removeAfter=false)
private File tempDirectory

@TemporaryFile
private File tempDirectory

The first one in the listing will create a directory with a random name. After the test the directory will still be there. The second one will create a file (with random name) and the file will be removed after the test has finished.
The location of the files created is still under discussion, But probably we will go for the java temp directory…

You can leave suggestions, features request or ideas on the bottom and we will take them into account ! thanks in advance!

We hope you will have as much fun using the new module as we had writing it!

Unitils 3.2

The Unitils 3.2 Release is live !

3.2 Is mainly a bug fix release. Why not the 4.0 ? We had some extra ideas for the 4.0 that will take some extra time to implement. So until the 4.0 is mature we will keep the 3.x branch alive and stable.  We will even start adding more features in the near future.

So what’s in the 3.2 release.

Fixes and features :

  • The famous Lenient dates ‘bug’ has been fixed. Even when you putted your  Dates.STRICT they still where handled lenient, this has an effect on the reflectionAssert as well on the easymock matcher. So if your test starts failing with date errors, you have discovered a bug, or you should set the matcher Dates to Dates.LENIENT .
  • The dummy Number bug : The new dummy won’t give any classcast exceptions anymore when working with the different number types. And the functionality has changed a bit.  Take for example this listing :
    @Dummy
    private Person person
    public void personTest(){
     Assert.assertNotNull(person.getAddress().getStreet());
    }
    

    With the old dummy implementation the getAddress would return null and the getStreet would trigger a nullpointerException. With the new dummy it wont, the getAddress will just return a new dummy and the street will return a dummy if its an object for an empty String when its a String.  If its not possible to create a dummy the defaults will be usefor a string : empty string
    for a number (int, Integer, long, Long, BigDecimal, …) : zero
    And for the collection a dummy (since they are just objects)
    Array : an empty array
    any final class will be returned as NULL.

    Be cautious when using a dummy object, when checking your behavior you want a mock or a real object and not a dummy. The dummy is only to be used when you don’t care about whats in the object, you just want to pass log statements and the occasional not null check!

  • The mocks now have support for an any matcher. So if you cont care about what content is passed to your mock, this one can help you out !
    userDaoMock.returns(asList(user1, user2)).getUsersForIds(any(List.class));
    
  • In 3.2 we’ve added an extra assertionClass, the SqlAssert. We are big fans of the @expectedDataset and encourage everyone to use it. But sometime it just not good enough, for these rare occations we added the sqlAssert class. It works in the the same transaction as your test, or you can add a datasource yourself. You can count, assert on a single row, or an multiple rows.  The perfect usecase is for example testing a delete ! since thats not possbible with dbunit.
    SqlAssert.assertCountSqlResult("select count(*) from person where name = 'IShouldHaveBeenDeleted'", 0L);
    

    The current possibilities are rather limited, but that’s done on purpose, we would like to have the users feedback on what they use and what they would like,  so we can extend it in future versions and make it the perfect addon for testing your database.
    So be sure to check it out and provide us some feedback !

  • The UnitilsDataSourceFactoryBean will now return a proxied datasource as it was intended.  This fix only has impact when your using spring together with a JPA implemenation or hibernate or any other orm you wire in spring.
  • And last but not least the unitils tutorials have been updated and enhanced. Be sure to check them out on untils.org

Try out the 3.2 and provide us with feedback, found bugs, feature requests, … Will give them a close look an if its possible put in the 3.3 of the 4.0.

For the ones who are happy the 3.2 is out! be sure to check in regularly because the 3.3 is already scheduled for the end of October! We’ll post a sneak preview of the new features on here soon !

And remember : if it’s not worth testing its not worth writing.

Why this blog

Yab.

With this blog we want to share our experience on how to write clean testable javacode. Once you have testable code you’ll find yourself in a situation where testing becomes trivial.

When you use a full-stack testing frameworks as unitils you’ll become very efficient in writing Unit / Integration / System tests.