Using JUnit from the Command Line

JUnit is a unit testing framework for Java that helps programmers write and run automated tests. When using JUnit for testing, the programmer typically writes many small tests to automatically check that a program behaves as expected. Often, the programmer will write one or more tests for each method. For the Yahtzee problem in Lab 02, I have written one test for each method. Each test tries some rolls that should cause the tested method to return false, and some rolls that should cause the tested method to return true; the test invokes the method for each roll and checks that the returned value is as expected.

Using JUnit from the command line is complicated by the fact that CSE1020 does not really explain how to create packages in Java. The Java suite of tools expect to find files in a directory structure that mimics the package structure. Because all of our files in the package cse1030, you need to make a directory named cse1030 and move your files into that directory. Assuming that you are in the directory containing your Java files, copy and paste the following commands into your terminal:

mkdir cse1030
mv Yahtzee.java cse1030
mv YahtzeeTest.java cse1030

Before you can compile your files, you need to specify the location of external libraries (such as the location of the jar files containing JUnit and cse1030.Die). The most convenient way to do this is to set the shell variable CLASSPATH. Copy and paste the following command into the terminal window you want to use to compile and run your programs:

setenv CLASSPATH /cse/dept/www/course/1030/junit-4.10.jar:/cse/dept/www/course/classpath/1030Z/lab01.jar:.

Now you can compile your Java files; copy and paste the following commands into your terminal:

javac cse1030/Yahtzee.java
javac cse1030/YahtzeeTest.java

To run JUnit, copy and paste the following commands into your terminal:

java org.junit.runner.JUnitCore cse1030.YahtzeeTest

Unfortunately, the command line version of JUnit produces a lot of output when tests fail! If you scroll your terminal up to where you started the test you should see something like:

java org.junit.runner.JUnitCore cse1030.YahtzeeTest
JUnit version 4.10
.E.E.E.E.E.E
Time: 0.009
There were 6 failures:
1) testIsFullHouse(cse1030.YahtzeeTest)
java.lang.AssertionError: [4, 6, 1, 2, 4, ]
        at org.junit.Assert.fail(Assert.java:93)
        at org.junit.Assert.assertTrue(Assert.java:43)
        at org.junit.Assert.assertFalse(Assert.java:68)
        at cse1030.YahtzeeTest.testIsFullHouse(YahtzeeTest.java:69)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
...

Here we see that 6 tests failed. The first test that failed was the test for a full house. We see that the test failed on line 69 of YahtzeeTest.java:

        at cse1030.YahtzeeTest.testIsFullHouse(YahtzeeTest.java:69)

Line 69 is testing a roll that is guaranteed not to be a full house using the method Yahtzee.isFullHouse, which currently always returns true.

// line 69 of YahtzeeTest
assertFalse(toString(dice), Yahtzee.isFullHouse(dice));

The assertFalse method is checking if the value returned by Yahtzee.isFullHouse(dice) is false; if not, then an exception is thrown which JUnit catches. The test is deemed to have failed, and JUnit proceeds to another test.

If you scroll through the output you will see that the other five tests have also failed.

To proceed, you need to implement the methods in Yahtzee.java so that they are correct. You can run JUnit every time you make a change in your source code; this will help you debug your code. When you have correctly implemented all of the methods and run JUnit you should see the following:

java org.junit.runner.JUnitCore cse1030.YahtzeeTest
JUnit version 4.10
......
Time: 0.017

OK (6 tests)