FileDocCategorySizeDatePackage
TestCase.javaAPI DocphoneME MR2 API (J2ME)21854Wed May 02 18:00:00 BST 2007com.sun.midp.i3test

TestCase

public abstract class TestCase extends Object
The main class for writing integrated internal interface (i3) tests. Tests should create a subclass of TestCase and implement the runTests() method. This method is responsible for running all of the tests. Tests consist of a test declaration followed by one or more assertions. The declaration is a call to the declare() method, which simply establishes a name for the set of assertions to follow. The assertions are made through calls to the assert*() family of methods. The framework considers it an error if any assertions are made prior to a call to declare(), or if there is a call to declare() with no subsequent calls to assert().

The TestCase class and its assert() methods are loosely based on the JUnit TestCase class. JUnit uses reflection to find test methods. Since reflection isn't present in CLDC, we need to have a runTests() method that calls them explicitly.

JUnit, in contrast to other test frameworks, doesn't return a result from each test. Instead, each test simply makes assertions, and only assertions that fail are flagged. The i3 tests follow the JUnit approach. For this reason, there is no pass() method one might expect to see corresponding to the fail() method.

While it's not a requirement, it's conventional for the TestCase subclass to reside in the same package as the code under test. This will allow the tests access to package-private variables and methods.

Each of the different assert() calls has an optional message parameter. This message is emitted only when the assertion fails and should be written with this in mind.

For "negative tests" that require an exception to be thrown, a suggested style is to record the fact that the correct exception was thrown in a boolean variable. This variable can then be tested using one of the assert() calls. This is probably preferable to placing calls to fail() in the midst of the test method. See testThree() in the example below.

The framework will catch any Throwable thrown by the tests and will log a message and count the occurrence as an error. This allows tests to be written more simply, because they can rely on the framework to catch everything. In support of this, the runTests() method has been defined with a 'throws Throwable' clause.

A general rule is that tests should run independently of each other. That is, tests should not leave any side effects that other tests rely on or that could cause them to fail. Typically, tests should create fresh objects for testing instead of reusing objects from other tests. If a test has any external side effects, such as creating threads or opening files, the test should be coded with a 'finally' clause that attempts to clean up after itself. See testFour() in the example below.

Example:


import com.sun.midp.i3test;
package java.lang;

public class SampleTest extends TestCase {
void testOne() {
int i = 1 + 1;
assertEquals("integer addition failed", 2, i);
}

void testTwo() {
Object x = new Object();
assertNotNull("Object constructor returned null", x);
}

void testThree() {
StringBuffer sb;
boolean caught = false;
try {
sb = new StringBuffer(-1);
} catch (NegativeArraySizeException e) {
caught = true;
}
assertTrue("no exception thrown", caught);
}

void testFour() {
Thread thr = new Thread(...).start();
try {
// ...
} finally {
thr.interrupt();
}
}

public void runTests() {
declare("testOne");
testOne();
declare("testTwo");
testTwo();
declare("testThree");
testThree();
declare("testFour");
testFour();
}
}

Fields Summary
static boolean
verbose
private static com.sun.midp.security.SecurityToken
internalSecurityToken
static boolean
tokenEnabled
static int
totalCases
static int
totalTests
static int
totalAsserts
static int
totalFailures
static int
errorClassNotFound
static int
errorConstructorException
static int
errorNotTestCase
static int
errorTestRunThrows
static int
errorNoTests
static int
errorAssertWithoutTest
static int
errorTestWithoutAssert
static TestCase
currentTestCase
static String
currentTest
static int
currentNumAsserts
Constructors Summary
public TestCase()
Constructs a TestCase. Since TestCase is an abstract class, this constructor is called only at the time a TestCase subclass is being constructed.

        if (verbose) {
            p("## TestCase " + this.getClass().getName());
        }
        currentTestCase = this;
        currentTest = null;
        totalCases++;
        currentNumAsserts = 0;
    
Methods Summary
public voidassertEquals(java.lang.Object expected, java.lang.Object actual)
Asserts that two objects are equal according to the equals() method.

param
expected an object containing the expected value
param
actual an object containing the actual value

        assertEquals(null, expected, actual);
    
public voidassertEquals(java.lang.String message, java.lang.Object expected, java.lang.Object actual)
Asserts that two objects are equal according to the equals() method. Two null references are considered to be equal.

param
message the message to be emitted if the assertion fails
param
expected an object containing the expected value
param
actual an object containing the actual value

	boolean isequal = (expected == actual);
        
        // If references aren't identical, call equals() only when
        // both references are non-null.

	if (!isequal && expected != null && actual != null) {
	    isequal = expected.equals(actual);
	}
	assertTrue(message, isequal);
	if (!isequal) {
	    p("  expected: " + expected + "; actual: " + actual);
	}
    
public voidassertEquals(int expected, int actual)
Asserts that two integer values are equal.

param
expected the expected value
param
actual the actual value

        assertEquals(null, expected, actual);
    
public voidassertEquals(java.lang.String message, int expected, int actual)
Asserts that two integer values are equal.

param
message the message to be emitted if the assertion fails
param
expected the expected value
param
actual the actual value

        assertTrue(message, expected == actual);
	if (expected != actual) {
	    p("  expected: " + expected + "; actual: " + actual);
	}
    
public voidassertFalse(boolean condition)
Asserts that condition is false.

param
condition the condition asserted to be false

        assertTrue(null, !condition);
    
public voidassertFalse(java.lang.String message, boolean condition)
Asserts that condition is false.

param
message the message to be emitted if the assertion fails
param
condition the condition asserted to be false

        assertTrue(message, !condition);
    
public voidassertNotNull(java.lang.Object object)
Asserts that the object reference is not null.

param
object the reference to be tested

        assertTrue(null, object != null);
    
public voidassertNotNull(java.lang.String message, java.lang.Object object)
Asserts that the object reference is not null.

param
message the message to be emitted if the assertion fails
param
object the reference to be tested

        assertTrue(message, object != null);
    
public voidassertNotSame(java.lang.Object expected, java.lang.Object actual)
Asserts that two references do not point to the same object, using the == operator.

param
expected a reference to the expected object
param
actual a reference to the actual object

        assertNotSame(null, expected, actual);
    
public voidassertNotSame(java.lang.String message, java.lang.Object expected, java.lang.Object actual)
Asserts that two references do not point to the same object, using the == operator.

param
message the message to be emitted if the assertion fails
param
expected a reference to the expected object
param
actual a reference to the actual object

        assertTrue(message, expected != actual);
	if (expected == actual) {
	    p("  expected: " + expected + "; actual: " + actual);
	}
    
public voidassertNull(java.lang.Object object)
Asserts that the object reference is null.

param
object the reference to be tested

        assertNull(null, object);
    
public voidassertNull(java.lang.String message, java.lang.Object object)
Asserts that the object reference is null.

param
message the message to be emitted if the assertion fails
param
object the reference to be tested

        assertTrue(message, object == null);
	if (object != null) {
	    p("  actual: " + object);
	}
    
public voidassertSame(java.lang.Object expected, java.lang.Object actual)
Asserts that two references point to the same object, using the == operator.

param
expected a reference to the expected object
param
actual a reference to the actual object

        assertSame(null, expected, actual);
    
public voidassertSame(java.lang.String message, java.lang.Object expected, java.lang.Object actual)
Asserts that two references point to the same object, using the == operator.

param
message the message to be emitted if the assertion fails
param
expected a reference to the expected object
param
actual a reference to the actual object

        assertTrue(message, expected == actual);
	if (expected != actual) {
	    p("  expected: " + expected + "; actual: " + actual);
	}
    
public voidassertTrue(java.lang.String message, boolean condition)
Tests the assertion that the boolean condition is true. If the condition is true, this method simply updates some statistics and returns. If the condition is false, the failure is noted and the message is emitted, along with an indication of the current TestCase and the name of the test currently being run. The message string should be phrased in a way that makes sense when the test fails. See the example in the class documentation.

param
message the message to be emitted if the assertion fails
param
condition the condition asserted to be true

        if (currentTest == null) {
            p("ERROR assert \"" + message + "\" not part of any test");
            errorAssertWithoutTest++;
            return;
        }

        currentNumAsserts++;
        totalAsserts++;

        if (verbose) {
            p("## " + totalAsserts + ": " + message);
        }

        if (!condition) {
            totalFailures++;
            String m = "FAIL " + currentTestCaseName();
            if (currentTest != null) {
                m += "#" + currentTest;
            }
            if (message != null) {
                m += ": " + message;
            }
            p(m);
        }
    
public voidassertTrue(boolean condition)
Asserts that condition is true.

param
condition the condition to be tested

        assertTrue(null, condition);
    
static voidcleanup()
Cleanup after running a test.

        if (currentTest == null) {
            p("ERROR " + currentTestCaseName() + " has no tests");
            errorNoTests++;
        } else if (currentNumAsserts == 0) {
            p("ERROR no asserts in test case " + currentTestCaseName() +
                    " test " + currentTest);
            errorTestWithoutAssert++;
        }

        currentTestCase = null;
        currentTest = null;
    
static java.lang.StringcurrentTestCaseName()
Return the name of the current test case.

return
the name of the class for the current test case.

        return currentTestCase.getClass().getName();
    
public voiddeclare(java.lang.String testName)
Declares that the set of assertions that follow this call belong to a test named testName. The framework considers it an error if no calls to any of the assert() methods follow a call to declare().

param
testName the name of the test

        if (testName == null) {
            throw new NullPointerException("test name is null");
        }

        if (verbose) {
            p("## test " + testName);
        }

        if (currentNumAsserts == 0 && currentTest != null) {
            p("ERROR no asserts in test case " + currentTestCaseName() +
                " test " + currentTest);
            errorTestWithoutAssert++;
        }

        currentTest = testName;
        totalTests++;
        currentNumAsserts = 0;
    
public voidfail()
Signals an unconditional assertion failure.

        assertTrue(null, false);
    
public voidfail(java.lang.String message)
Signals an unconditional assertion failure.

param
message the message to be emitted, explaining the failure

        assertTrue(message, false);
    
protected com.sun.midp.security.SecurityTokengetSecurityToken()
Gets the system's internal security token. This is useful for testing sensitive interfaces that require a security token parameter. This returns a valid security token only when called within the context of a call to runTests() inside a TestCase. At other times it will throw a SecurityException.

return
the internal security token
throws
SecurityException if not called from within runTests()

        if (tokenEnabled) {
            return internalSecurityToken;
        } else {
            throw new SecurityException();
        }
    
protected booleangetVerbose()
Reads the verbose flag.

return
true if in verbose mode

        return verbose;
    
public voidinfo(java.lang.String s)
If in verbose mode, print information.

        if (verbose) {
            p(".# "+s);
        }
    
static voidp(java.lang.String s)
Print the string.

param
s the string to print on a new line.

        System.out.println(s);
    
static voidperror(int nerr, java.lang.String errstr)
Print the number of errors with the category.

param
nerr the number of errors in the category
param
errstr the description of the errors

        if (nerr != 0) {
            System.out.println("  " + nerr + " " + errstr);
        }
    
static voidreport()

        System.out.print("Test run complete: ");
        System.out.print(totalCases
            + (totalCases == 1 ? " testcase " : " testcases "));
        System.out.print(totalTests
            + (totalTests == 1 ? " test " : " tests "));
        System.out.println(totalAsserts
            + (totalAsserts == 1 ? " assertion" : " assertions"));

        if (totalFailures != 0) {
            System.out.println(totalFailures
               + (totalFailures == 1 ? " FAILURE!!!" : " FAILURES!!!"));
        }

        int totalErrors = 
            errorClassNotFound +
            errorNotTestCase +
            errorConstructorException +
            errorTestRunThrows +
            errorNoTests +
            errorAssertWithoutTest +
            errorTestWithoutAssert;

        if (totalErrors != 0) {
            System.out.println(totalErrors
                + (totalErrors == 1 ? " ERROR!!!" : " ERRORS!!!"));
            perror(errorClassNotFound, "test class not found");
            perror(errorConstructorException, "constructor threw exception");
            perror(errorNotTestCase, "class not subclass of TestCase");
            perror(errorTestRunThrows, "test run threw exception");
            perror(errorNoTests, "no tests declared");
            perror(errorAssertWithoutTest, "asserts outside of any test");
            perror(errorTestWithoutAssert, "tests with no asserts");
        }
    
static voidreset()
Reset the counters of all errors and exceptions.

        totalCases = 0;
        totalTests = 0;
        totalAsserts = 0;
        totalFailures = 0;
        currentNumAsserts = 0;

        errorClassNotFound = 0;
        errorConstructorException = 0;
        errorNotTestCase = 0;
        errorTestRunThrows = 0;
        errorNoTests = 0;
        errorAssertWithoutTest = 0;
        errorTestWithoutAssert = 0;
    
static voidrunTestCase(java.lang.String testCaseName)
Run the named test case.

param
testCaseName the class name of the test case


    // ==================== static implementation ====================

                       
        
        Class clazz;
        Object obj;
        TestCase tc;

        if (verbose) {
            System.out.println("## running test case " + testCaseName);
        }

        try {
            clazz = Class.forName(testCaseName);
        } catch (ClassNotFoundException cnfe) {
            System.out.println(
                "ERROR test class " + testCaseName + " not found");
            errorClassNotFound++;
            return;
        }

        try {
            obj = clazz.newInstance();
        } catch (Throwable t) {
            System.out.println("ERROR test class " + testCaseName +
                " constructor threw " + t);
            errorConstructorException++;
            return;
        }

        try {
            tc = (TestCase)obj;
        } catch (ClassCastException cce) {
            System.out.println("ERROR test class " + testCaseName +
                " not a subclass of TestCase");
            errorNotTestCase++;
            return;
        }

        try {
            tokenEnabled = true;
            tc.runTests();
        } catch (Throwable t) {
            String m = "ERROR " + currentTestCaseName();
            if (currentTest != null) {
                m += "#" + currentTest;
            }
            m += " threw " + t;
            p(m);
            t.printStackTrace();
            errorTestRunThrows++;
        }

        tokenEnabled = false;
        cleanup();
    
public abstract voidrunTests()
Runs all the tests for this TestCase. This is an abstract method that must be implemented by the subclass. The implementation of this method should run all of the tests provided in this TestCase. This method can also be used to initialize and tear down any state that might need to be shared among all the tests.

A suggested organization is to have runTests() alternate calling declare() and an internal method that implements the test. One could write the declare() method as part of the internal test method, but consolidating all calls in runTests() makes it a little easier to ensure that each test has its own call to declare(). See the example in the class documentation.

static voidsetVerbose(boolean v)
Set the verbose output flag.

param
v true to enable verbose output

        verbose = v;