/*
* Javolution - Java(TM) Solution for Real-Time and Embedded Systems
* Copyright (C) 2007 - Javolution (http://javolution.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javolution.testing;
/**
* <p> This class represents a test case which can be used for validation,
* performance and regression tests.</p>
*
* <p> The structure of a test case is as follow:[code]
* class MyTestCase extends TestCase {
*
* // Prepares data/state in which to run the test.
* public void setUp() { ... } // Optional
*
* // Executes the test possibly exercising the function tested multiple times.
* public void execute() throws Throwable { ... } // Mandatory.
*
* // Returns the number of times the function tested has been exercised (default 1).
* public int count() { ... } // Optional
*
* // Validates the test results and possibly check for limit cases or exceptions.
* public void validate() throws Throwable { ... } // Mandatory.
*
* // Cleanups after execution (e.g. to release resources).
* public void tearDown() { ... } // Optional
* }[/code]
* It should be noted that some testing contexts (e.g. {@link TimeContext})
* may run the sequence: setUp, execute and tearDown multiple
* times to calculate for example the average execution time,
* {@link #validate validation} in that case is performed only once
* after the last execution.[code]
* public class TypeFormatParseInt extends TestCase {
*
* static final int N = 1000; // Number of random samples.
* int[] _expected = new int[N];
* int[] _actual = new int[N];
* String[] _strings = new String[N];
*
* public void setUp() {
* for (int i = 0; i < _expected.length; i++) {
* _expected[i] = MathLib.random(Integer.MIN_VALUE, Integer.MAX_VALUE);
* _strings[i] = String.valueOf(_expected[i]);
* }
* }
*
* public void execute() {
* for (int i = 0; i < N; i++) {
* _actual[i] = TypeFormat.parseInt(_strings[i]);
* }
* }
*
* public int count() {
* return N;
* }
*
* public void validate() {
*
* // Compares expected versus actual (for random values).
* TestContext.assertArrayEquals(_expected, _actual);
*
* // Supplementary tests to check for limit cases.
* TestContext.assertEquals(Integer.MIN_VALUE, TypeFormat.parseInt("-2147483648"));
* TestContext.assertEquals(0, TypeFormat.parseInt("0"));
* TestContext.assertEquals(Integer.MAX_VALUE, TypeFormat.parseInt("2147483647"));
*
* // Checks exceptions raised.
* TestContext.assertException(NumberFormatException.class, new Runnable() {
* public void run() {
* TypeFormat.parseInt("2147483648"); // Overflow
* }
* });
* TestContext.assertException(NumberFormatException.class, new Runnable() {
* public void run() {
* TypeFormat.parseInt("123E4"); // Invalid Character
* }
* });
* }
* }[/code]</p>
*
* <p> Test cases may be {@link TestContext#run(javolution.testing.TestCase)
* run} individually or as part of a {@link TestSuite}. If an error occurs
* the location of the assert failing is usually available (a hyperlink
* in Netbeans and Eclipse).
* <pre>
* ...
* > [test] TypeFormat.parseDouble(CharSequence)
* > <font color="#FF0055">[error] Array element at 840, expected 2.078139623637765E-308 but found 2.0781396236377647E-308
at javolution.TypeFormatTest$ParseDouble.validate(TypeFormatTest.java:419)</font>
* </pre></p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 5.3, February 27, 2009
* @see TestContext
*/
public abstract class TestCase {
/**
* Indicates if this test case has to be ignored.
*/
boolean _isIgnored;
/**
* Returns the name of this test case. The default implementation
* returns the class name.
*
* @return the test case name.
*/
public String getName() {
return this.getClass().getName();
}
/**
* Default constructor.
*/
protected TestCase() {
}
/**
* Selects whether or not this test case should be ignored. If the
* test case is ignored it is not executed, but the test context
* will usually indicate that the test is being ignored.
*
* @param isIgnored <code>true</code> if test case is ignored;
* <code>false</code> otherwise.
* @return this test case.
*/
public TestCase ignore(boolean isIgnored) {
_isIgnored = isIgnored;
return this;
}
/**
* Indicates whether or not this test case should be ignored.
*
* @return <code>true</code> if this test case is ignored;
* <code>false</code> otherwise.
*/
public boolean isIgnored() {
return _isIgnored;
}
/**
* Prepares the test case execution (the default implementation does
* nothing).
*/
public void setUp() {
// Does nothing.
}
/**
* Executes this test case (possibly multiple times in which case
* the {@link #count()} method should be overriden).
*/
public abstract void execute() throws Exception;
/**
* The number of times the test case is exercised (default <code>1</code>).
*
* @return the number of test case occurences in {@link #execute}.
*/
public int count() {
return 1;
}
/**
* Validates the test results and possibly checks for limit cases
* or exceptions.
*/
public abstract void validate() throws Exception;
/**
* Cleanup once test is complete (the default implementation does
* nothing).
*/
public void tearDown() {
// Does nothing.
}
/**
* Returns the <code>String</code> representation of this test case.
*
* @return <code>this.getName()</code>
*/
public String toString() {
return getName();
}
}