Sunday, June 10, 2007

Testing your code

Testing is very important. What constitutes testing? Well that depends. If your application is mostly self contained, meaning it takes some command line args then spits out some data, then unit testing probably would be all you need. Other times your application must interact with one or more systems, so it would be good to test that all systems integrate nicely.

In this post I'm going to give my opinion on testing, and the two larger types I use and how and when to apply them.


Unit Testing

What do I mean by unit testing? I mean the following:

1. Your tests all run very fast, and the whole suite of tests runs in or around 5-10 seconds.
2. Every (yes every) time you compile the unit test suite is run to find errors in your code. Now you see why they must run fast.

To have fast running unit tests it is often very important to use interfaces between application objects. This will allow you to create mock versions of objects for testing.

An example: you have a remote HTTP interface with an implementation that allows HTTP calls to a network server. Now say you want to test an object that uses this remote HTTP interface. If you use the real implementation of the HTTP interface, the one you create for use in your application, you will encounter some problems. At some point you will compile, and your unit tests will fail because the HTTP object cannot reach the HTTP server, or maybe the server is on the fritz and returns the wrong data. This remote HTTP call could also be slow, causing your tests to break the 5-10 second 'rule'.

What is my solution? Create mock objects that implement an interface but don't do much. Some methods return nothing, so you may just create an empty method. Others might return an object, so simply create that objects configure it and return it. If you create a mock version of the HTTP interface you can control exactly what happens when it's methods are run.

Creating the mock objects allows consistency in your tests. Unit tests are all about consistency. If nothing else your unit tests should always perform exactly the same, with the only variable(s) being the object(s) being tested. What this means is that if you are having tests "integrate" with other systems it is no longer a unit test... Which leads me to the next part of this post.

Integration Testing

Integration testing is just as important as unit testing. If you are building an application that must integrate with another system you may want to write tests that test your application against the system to integrate with. These tests can let you gain knowledge such as: where things are slow between the two systems, test what happens in various scenarios i.e. testing for error handling, make sure that the system you integrate with can handle the load you put on it, or any other type of integration. Integration tests are more important to run a few times a day while you are actively working on a project. They often to do not run very fast, and could take many minutes or even hours :(

1 comment:

Anonymous said...

Great work.