Saturday, March 14, 2009

Managing Your Tests

So I've been writing some code for a while and knocking out a few stories and the code base is growing, and so are the tests. The thing that allows you to refactor and to explore better ways of doing something is having good tests that pass. And by good tests, I mean that there are both unit tests and integration tests on all classes. Before you write any code, you have to write a test. If you find a piece of functionality that you can't test, try pulling it apart or isolating the un-testable portion as much as possible. I like to think of the tests as a safety net for your code. The tests describe the behavior of my application and so as long as all the tests pass, the code is free to be massaged into whatever I like.

However, an interesting issue arrises as the tests grow. The tests begin to exhibit some code smells. There's probably some code duplication or possibly some tests that test the same behvavior. Especially with some extensive integration tests. Eventually, I start to want to refactor my tests. Which really makes sense because if you don't maintain your tests they will become unusable and you eventually try to get around them. So refactoring the tests really is a necessity.

Now the danger here is, how do you know that you didn't break a test? I write tests for my code so that I can refactor my code but there is no tests for my tests to ensure that I didn't break the tests. I can run them against the codebase and ensure that they still pass, but it's easy to get false positivies that way.

I've been running into this at work recently and I'm trying to find a good principle or something that will ensure the stability of the tests through refactoring. Unit tests are usually fairly easy to refactor. The tests themselves are straight forward and you see real easily what they're testing. Integration tests are not so clear, or at least they can be more challenging. My advice so far has been to make sure that there is good unit tests before you start refactoring the integration tests and only make small changes at a time and as much as possible verify all the changes all the time.

If anyone has some other comments or suggestions about what to do for refactoring test, please let me know!

1 comment:

  1. I asked a few people around the office and got their input and the consensus was the general principle is to refactor your code towards easy to make changes and refactor your tests for readability. Your tests document your code. Duplication is alright as long as it's still readable.

    ReplyDelete