Summary: In this lab, you will set up your unit testing
environment and practice writing unit tests for our tester
library.
Preparation
-
Create a directory for this lab:
mkdir somewhere/testing
-
Go to your new directory:
cd somewhere/testing
-
Copy the files for this lab to your new directory:
cp ~weinman/public_html/courses/CSC207/2010S/labs/code/testing/tester.jar .
cp ~weinman/public_html/courses/CSC207/2010S/labs/code/testing/IntegerBag.class .
-
The routines for our testing environment are all packaged
together in the Java ARchive
tester.jar that you
just copied. In order to use them, you will need to tell Java
where they live. You can either do every time you
compile and run a test suite (which can get quite tedious), or
you can do it just once, when your shell environment is
configured. I prefer the latter approach, which you can do with
the following steps.
-
Open the file ~/.bashrc in your favorite text editor
-
Somewhere near the end, but before any final export
commands, add the following line:
CLASSPATH=.:somewhere/testing/tester.jar
where somewhere is the directory where you
created a place for this lab. This command tells the JDK to
look for classes in whatever the current directory is
("."), but also in the jar file.
-
If there is already a line with an export command
near the end, add the environment
variable CLASSPATH to the list. In other words,
there may be other variables listed, but be sure after the
declarations listed in step 2, you have a line like the
following:
export PATH EDITOR VISUAL CLASSPATH
-
Make sure these changes take effect in your current shell by
typing the following at the command line:
$ source ~/.bash_profile
They won't take effect globally until you log in again.
-
You can verify that the environment variable was added by
echoing it at the command line:
$ echo $CLASSPATH
-
Open the
Tester Overview page in a new browser tab for handy reference.
Exercises
Exercise 1
One of the files you copied is a class for doing some simple
operations on a bag (or set) of integer
numbers. Read
the JavaDoc
for IntegerBag to understand what the objects of
the class are to do.
Exercise 2
Create a class called
TestIntegerBag in the same
directory as the
IntegerBag.class file. Import the
all of the classes from the tester package to your class:
Exercise 3
Think about what sorts of things you may want to test about the
routines in
IntegerBag. What behaviors does the
documentation specify? What sorts of input can you create to ensure
correct functionality?
Add a variety of
IntegerBag objects as member variables
of your test class. (Note: you do not need to do this in a
constructor. Also, you can create and populate arrays on the fly
with
new Integer[]{1,2,3} .)
Exercise 4
Add an object method to your class for testing the
size()
operation. Remember that
Tester requires the test
methods to begin with the name
test. For instance:
IntegerBag empty = new IntegerBag(null);
// ...
public void testSize(Tester t)
{
/* Check size of empty bag */
t.checkExpect(empty.size(), 0, "size: Null/empty bag");
// more tests ...
}
When you are finished, make sure your class compiles.
Exercise 5
The typical way to check your tests is by including
a
main driver method in your test object class. Thus,
you will need to do the following:
-
Add a main method.
-
Create an instance of
TestIntegerBag inside your driver.
-
The
Tester class features the following method:
public static void runReport(java.lang.Object obj,
boolean full,
boolean printall)
This is your hook to run the tester for any object and produce a
test report. Your instance of TestIntegerBag should be
the first argument You can use the other to options to select whether
to print all tests and/or data from all results.
Add a call to this method and run your tests.
-
Experiment with the options
full
and printAll to see what the settings do (and which
you find most useful as a default).
-
You should find one category of error in
size. If you haven't detected it yet, re-read the constructor documentation carefully.
-
If you still haven't detected it, think about why the class
takes an array of reference types, rather than an array of
primitive types.
Exercise 6
-
testMax, may be incorrect. Develop a comprehensive
suite of tests in a method called testMax to see if you
can uncover bugs in the implementation.
-
Compile your test class and run your tests.
-
The method
product may also be incorrect. Develop a
comprehensive suite of tests in a method
called testProduct to see if you can uncover bugs in
the implementation.
-
Compile your test class and run your tests.
Exercise 7
One of the things you may have (should have!) found was exceptions
being thrown that you didn't expect. Due to the architecture of the
tester, an exception caused by your checks results in terminating
the test method you are in, so that no more checks in that method are
run. While other test methods will be run, you would have to fix the
bug (exception) in order to continue checks in that method.
You may proceed here by commenting out and documenting any checks
that give you unexpected exceptions so that you can continue with the
other checks in the test method.
Exercise 8
Conversely to the above situation, testing whether advertised bad
behavior actually occurs is also often important.
For this reason, the tester library also allows us to check whether
we actually get an exception when it is expected. Not only that, it will report
whether the exception was of the right type, and also had the
expected message with a method like the following
public boolean checkException(java.lang.String testname,
java.lang.Exception e,
java.lang.Object object,
java.lang.String method,
java.lang.Object... args)
Thus, to test whether the call to
min fails with our empty bag of numbers, as it should, we might write
checkException("Min: null empty bag",
new IllegalStateException(), // No exception message (tester cares)
empty, // Object we are testing
"min"); // Method to test
Note that the
args argument (used with ellipses because
they are optional and variable in number) are omitted
since
min takes no parameters.
-
Try this test and verify that it works.
-
What happens if you add a message to the expected exception?
I.e.,
new IllegalStateException("Busted!");
-
Test other cases of the advertised exceptions in the class. They
may be broken.