Do I always write a test?

I’ve just been reading the debate between Bob Martin and Jim Coplien on InfoQ, centred around Bob’s assertion that “nowadays it is irresponsible for a developer to ship a line of code he has not executed in a unit test.”

I have to confess… despite my desire for BDD, I don’t always do automated tests for everything. The place I’m most likely to skip automated tests is when something shows up in a GUI.

That might strike you as odd, if you know that BDD’s outside-in starts from the GUI and works downwards. It’s probably less odd if you also know that automated testing is no substitute for manual testing. Here are a couple of things for which I haven’t written a test.

From Hellbound, the Tetris game in JBehave’s examples:

public class AcceleratingHeartbeatBehaviour extends UsingMiniMock {{

    public void shouldBeatAfterElapsedTime() throws Exception {
        <Test code exists>
    }
    
    public void shouldBeatMoreQuicklyWithEachBeat() {
        // No way of ensuring this with automation. 
    }
    
    public void shouldStopAnyExistingTimerThreadsBeforeStarting() {
        // No way of ensuring this with automation. 
    }
    
    public void shouldMoveImmediatelyToNextWaitingPhaseWhenSkippingABeat() {
        // Nor this.
    }
    
    public void shouldNotBeatAfterBeingStopped() throws Exception {
        <There's some test code for this one too>    
    }
}

It’s not entirely true that there’s no way of ensuring these things with automation (and the main drawback here was the time it took, which spoils the < 5 second regression test suite). One could extract out clock classes, etc. But then, you're sacrificing readability and ease of design – a single class is enough. Why would you do this, anyway? The only way of telling whether the timing of a game is fast enough to be challenging but slow enough to be feasible is to play it!

It's much the same with this, from the same Game of Life and GameFrame class as the last post:

public class GameFrameBehaviour extends Behaviour {

    @Test
    public void shouldHaveAButtonForTheNextGeneration() throws Exception {
        <See last post for this code>
    }
    
    @Test
    public void shouldCreateCellsInGameCorrespondingToMouseClicks() {
        // I'm not putting any examples here, because in reality the
        // only way to tell if this works is to test it manually!
    }

}

I tried writing an automated test to check that mouse-clicks corresponded to cells appearing in the grid. I got it wrong; the automated test passed but the cells were appearing in the wrong place. I made the same mistakes with Swing’s coordinate system in both the test and the code. This time round I can’t even be bothered; it’s easier just to use it, check that I got it right, and never change the behaviour of the grid GUI again (at least, not without manual retesting).

There are other places where I’ll skip unit tests too – getters, mostly. I’ll even skip automated system-level tests if there isn’t an appropriate harness. I’ve done this in my own code; I’ve done this at client sites.

Do I feel guilty or unprofessional?

No.

Does it stop me describing how the class behaves?

No. I usually add empty methods to describe an aspect of behaviour that I don’t want to test. At least they get read; they also remind me that I have a missing test, and should use careful inspection if I change the code.

Does it mean that I can get away without testing it altogether?

No. I have to test it manually, from the GUI, instead.

But then, you’re doing that anyway… aren’t you? Because I think Bob would agree on one point with me: nowadays it is irresponsible for a developer to ship a line of code he has not tested, and all your tests are worthless if it doesn’t actually work.

This entry was posted in bdd. Bookmark the permalink.

2 Responses to Do I always write a test?

  1. anonymous says:

    In my opinion spending a large amount of time coming up with an automated unit test for code that has low risks associated with failure (must restart a game being played for personal entertainment) and a high difficulty factor in automated testing is just as unprofessional as NOT making automated tests when it isn’t difficult and adds significant value.

    When any project is started, one of the things that needs to be clearly defined are the risks and consequences of defects so that an appropriate test plan can be devised. The test plan for a project like the United States space shuttle program is going to look vastly different than a word processing application. Blindly applying any testing requirements, including automated unit tests, isn’t an effective development technique.

    – Nolan Egly

  2. sirenian says:

    High-five.

    I fully agree, and am slowly learning what it is that QAs actually do. Test plans – and knowing what to automate, what not to automate and what can’t be automated anyway – are elusive to me. I’m still finding this by trial and error on my breakable toys.

    Fortunately at client sites I have some very talented colleagues who deal with that kind of thing.

Comments are closed.