karldmoore development

A development oriented blog, containing anything I've been working on, reading or thinking about.

  • Subscribe

  • Twitter Updates

    Error: Twitter did not respond. Please wait a few minutes and refresh this page.

  • Disclaimer

    The opinions expressed here are my own and are not necessarily shared by my employer, any other organization, or any other individual. Any trademarked names or labels used in this blog remain the property of their respective trademark owners. No guarantees are made regarding the accuracy or usefulness of content on this blog, though every effort is made to be accurate.
  • Meta

Testing Times Concluded: There’s always tomorrow, isn’t there?

Posted by karldmoore on July 29, 2009

In the previous three articles we discussed the difficulties that can be encountered when introducing automated testing into a team and how to try and address these when they occur. Although the principles are very straight forward, many teams have great difficulty adapting to an automated testing approach. In the final part of this series, we take a look at why the testing shouldn’t wait for another day.

How can we get teams to write tests as they write code?

For many developers the biggest challenge to writing tests as they write the code is a behavioral one. They are not use to writing tests alongside the code and usually test-last once all the code has been written. Some developers do exactly the same thing when writing JavaDoc, with very similar results. If developers don’t like writing tests, they really don’t like writing lots of tests right at the end of a project. Typically when jobs like this are left right until the end of a project, they either don’t get done, or don’t get done very well.

The main problem with this approach is that the developer doesn’t really benefit from the tests during development. When the code is developed, there is a reliance on logging, debugging and manual testing to ensure the code works as expected. When changes are made to the code, the whole cycle must be repeated again. This feedback cycle can very quickly decrease the velocity of development.

By writing the tests at the same time as the functionality, it not only saves a marathon session of writing tests at the end of a project, it also means the tests are used to help develop the code. There is confidence in the changes being made, and if tests are continually run it’s easy to know which code change broke the tests. This leads to a much shorter feedback cycle when developing and subsequently over time, developers are more productive.

@Test(expected=IllegalArgumentException.class)
public void nameCannotBeNull() {
    // now we've finished coding
}

@Test(expected=IllegalArgumentException.class)
public void nameMustNotBeEmpty() {
    // it's time to write some tests
}

@Test(expected=IllegalArgumentException.class)
public void nameIsTooLong() {
    // I really wish I'd started sooner
}

Developers really don’t like writing lots of tests for code they’ve already written.

What about all the existing untested code?

If developers don’t like writing lots of tests at the end of a project, they really really don’t like writing tests for legacy code. This single task is one of the most hated and time consuming to complete. The typical problem is that the code wasn’t designed for testing, hence the code must be refactored before tests can be written. The real problem with this approach is that tests are actually supposed to catch changes that might break the code. It really is a catch-22 situation, as performing the refactoring to allow tests, may actually introduce changes which break the code.

Writing tests for legacy code can be extremely time consuming. One of the biggest problems (if it is actually possible to write tests), is that it isn’t always obvious what the code was supposed to do in the first place. Even if the original author is still working on the project, the code isn’t fresh in their mind, and as such, there is going to be an initial period of familiarisation. Even if this is successful, it can be extremely time consuming and sometimes very haphazard.

Can the project afford to not refactor the code and have limited test coverage? Can the developers risk making changes and potentially introduce bugs in the short-term thus allowing long-term stability? Ulimately there is a tough decision to make here, but the situation isn’t going to get any better. Retrospective testing costs more time and money as development progresses, can this be left for the time being or is it wiser to tackle this problem now? Fixing defects later in the process will inevitibly cost more time and money. Is manual testing alone sufficient enough to find enough of the defects?

When modifying or adding to legacy code I personally prefer either writing tests first, or performing the minimum amount of refactoring required to add tests. The sooner the code has tests, and the less code changes I have to make to allow testing, the happier I am.

public class TestsForReallyComplicatedCode {
    @Test
    public void todo() {
        // ok now I'm scared!
    }
}

Is it a really a good idea to let this problem get any worse?

Conclusion

Test-driven and test first development have become very fashionable over the past few years. Ensuring code has tests is one of the core Extreme Programming rules, but it can also be one of the most difficult to introduce to a team. Although the principles are very straight forward, many teams have great difficulty adapting to an automated testing approach. Some of these teams don’t have any existing testing strategies in place, meaning that incorporating automated testing into development seems like an unattainable goal. In this series of articles we’ve covered some of the common problems encountered when trying to incorporate testing into development including:

  • We DON’T do testing
  • I don’t write tests
  • I don’t know what I’m supposed to be testing
  • Nobody knows anything about testing
  • We aren’t allowed to write tests
  • How can we get teams to write tests as they write code?
  • What about all the existing untested code?

Developers are willing to write tests, they just need some guidance. Anyone trying to encourage the adoption of automated testing needs to make sure they are approachable and on hand throughout the process to answer any questions and try to quell any frustrations before they occur. Once developers understand how to write tests effectively, it soon becomes second nature to them. These are indeed testing times.

References

Advertisements

One Response to “Testing Times Concluded: There’s always tomorrow, isn’t there?”

  1. I just have to say this is an excellent series of articles. I’ve run into all of these at various points in my career, with projects in various states of completeness / unit-testlessness. I recently ran into a case where I was writing unit tests for code that obviously wasn’t written with testability or mocking in mind. I ended up having to make some pretty significant (scary, as you note) refactors, but the end result was better OO code and had the added bonus of having real unit test coverage!

    I agree that the “it works, don’t break it, why do we need tests” mantra is just as painful when you hear it from fellow developers and management. Any suggestions from your personal experience?

    Best,
    Peter

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: