A great New Idea for solving the JUnit dependency problem!

| | Comments (2)

I just stumbled across an older blog entry blog entry about JUnit which has helped me better understand the core of the debate over test dependencies. The article presents a justification for JUnit's practice of instantiating a new TestCase instance for every test method it runs. It leads off with an example:

public class Tester extends TestCase {
    public Tester(String name) {super(name);}
    private List list = new ArrayList();
    public void testFirst() {
        list.add("one");
        assertEquals(1, list.size());
    }
    public void testSecond() {
        assertEquals(0, list.size());
    }
}

and provides the following explanation about it:

Some people may not realize this, but both tests pass - and will pass in whichever order they are run. ... One of the key principles in JUnit is that of isolation - that is no test should ever do anything that would cause other tests to fail.

And I do kind of see his point: having all that shared data can definitely lead to fragile code if you aren't careful in the design of your class.

This got me to thinking, though: wouldn't it be great if Java had a way to declare a variable that could only be used *inside* a method? Sounds cool, huh? Maybe I should start a JSR for these things - I think I will call them "Local Variables."

These Local Variables would would be a huge win for JUnit users because they would offer a much simpler way to ensure that test methods operate on fresh data. Let me illustrate how I would see this working in the previous example - try to stay with me:

public class Tester extends TestCase {
    public Tester(String name) {super(name);}
    public void testFirst() {
        List list = new ArrayList();
        list.add("one");
        assertEquals(1, list.size());
    }
    public void testSecond() {
        List list = new ArrayList();
        assertEquals(0, list.size());
    }
}

Isn't that great? Wouldn't it be awesome if we could write tests this way?

</snotty>

Ok, ok, you get the point (I hope). And please don't get me wrong - I like JUnit and have found it very useful, modulo a few annoyances like this.

But the bottom line is that this whole 'test independence' feature that JUnit offers is rooted in a conflation of local and member variables. If you want to have state that is local to a method invocation, Java gives you a perfectly good way to do this.

But Java also gives you a mechanism for associating state with an instance, and there are plenty of valid reasons to want to use it when writing tests. Managing the state of an instance is a fundamental part of OO programming, and competent OO programmers know how to do it without making a mess of things.

By taking away instance variables, JUnit effectively insists that its users are not competent OO programmers. I find this just slightly irksome.

What I find disturbing is that so many JUnit users so vehemently seem to agree.

2 Comments

Mike O'Keefe said:

Wow, since when is Fowler the author of JUnit? According to http://www.junit.org/index.htm, it was written by Kent Beck and Erich Gamma. Fowler did write a book with Kent Beck, on Extreme Programming, however, perhaps that's the source of this misconception.

Ah, you're quite right. My blog and I stand corrected.

Leave a comment

About

My name is Patrick Calahan.

I live in San Francisco.

I do product development and consulting on Java and Business Intelligence.

This is my blog.

Contact

About this Entry

This page contains a single entry by published on March 19, 2005 10:17 AM.

No, Dependent Test Methods are not Evil (and you know it, Cedric) was the previous entry in this blog.

One Theme, Two great Ads is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Powered by Movable Type 4.01