The World's Simplest Unit Testing Framework

I describe “the world's simplest Unit testing framework” for teaching Java to beginners.

???I teach computer science at San Jose State University. In my experience, the habits from the first programming course stay with students for a long time and are very difficult to break. (I am always amazed how many seniors in my software engineering course still use Notepad to edit their Java files.) I want to get the freshmen to embrace test-driven development right from the get-go.

???JUnit 4 is nice and simple. Just add @Test, and use assert, which is a standard Java feature. But unfortunately, that's still too hard for beginners. Did you every try to get a bunch of freshmen to add a JAR to their class path? It's not a pretty sight.

So, this is what I ended up doing. I require that every program prints out the value that the student expects:

public class BankAccountTester
{
   public static void main(String[] args)
   {
      BankAccount momsSavings = new BankAccount(1000);
      momsSavings.deposit(100);
      double balance = momsSavings.getBalance();
      System.out.println("Balance: " + balance);
      System.out.println("Expected: 1100");
   }
}

The printout is

Balance: 1100
Expected: 1100

That's the “green bar” moment in the world's simplest unit test framework.

I wrote an Ant extension that automatically checks the output and deals with silly issues such as roundoff:

Balance: 1034.2999999997
Expected: 1034.30

The students don't run Ant; that's just for my grading automation. My grading script contains an entry

    <java classpath="${submit.dir}"
          classname="${mainclass}"
          failonerror="true"
          outputproperty="mainclass.out"
          fork="true" />
    <echo message="${mainclass.out}" />
    <condition property="tester.fail" value="Output not as expected">
      <not>
        <asexpected value="${mainclass.out}" tolerance="${test.tolerance}" />
      </not>
    </condition>

There you have it. TWSUTF is System.out.println("Expected: ...") and an Ant condition that checks the output.

???Big deal, right? Well, it turns out to be a bigger deal than I thought. The next assignment asks students to write a class IceCreamCone. And I cruelly ask them to write the test first.

public class IceCreamConeTester
{
   public static void main(String[] args)
   {
      double height = 6;
      double diameter = 1;
      IceCreamCone waffleCone = new IceCreamCone(height, diameter);
      double volume = waffleCone.getVolume();
      System.out.println("Volume: " + volume);
      System.out.println("Expected: How the !@#$ am I supposed to know?");
   }
}

Now I have them where I want them. They have to figure out the answer by hand for at least one case. That's very different from running the program and saying “ok, looks about right”.

Of course, after a few weeks, the simple tests get tedious. We want multiple tests without writing lots of static methods—another no-no in the intro course. And we want the other tests to keep on trucking when one of them throws an exception. That's the time to break out JUnit. Now it solves a problem that the students have.

What do you think? Should students get immersed in TDD in their first Java course, or would it be a better use of time to learn another sorting algorithm, or some GUI programming, or whatever?