001: package com.reeltwo.jumble.fast;
002:
003: import junit.framework.Test;
004: import junit.framework.TestResult;
005:
006: /**
007: * A test suite which times test runs. The idea is that tests are run and sorted
008: * in order of runtime. Example usage: <BR>
009: * <BR>
010: *
011: * <PRE>
012: *
013: * TimingTestSuite suite = new TimingTestSuite (new Class[] { MathTest.class,
014: * StringTest.class});
015: *
016: * suite.run(new TestResult());
017: * TestOrder order = suite.getOrder();
018: * </PRE>
019: * <BR>
020: * This can then be used by Jumble to run the tests on the mutated class in
021: * order so that it fails quickly.
022: *
023: * @author Tin Pavlinic
024: * @version $Revision: 496 $
025: */
026: public class TimingTestSuite extends FlatTestSuite {
027: public static final boolean DEBUG = false;
028:
029: /** The runtimes for the tests */
030: private long[] mRuntimes = null;
031:
032: /**
033: * The test classes used to create this suite. Only so they can be passed to
034: * the <CODE>TestOrder</CODE>
035: */
036: private Class[] mTestClasses;
037:
038: /**
039: * Constructs a test suite from the test classes given in <CODE>testClasses
040: * </CODE>
041: *
042: * @param loader a <code>ClassLoader</code> used to load the test classes.
043: * @param classNames an array of the names of classes of test suites to run
044: * @exception ClassNotFoundException if an error occurs.
045: */
046: public TimingTestSuite(ClassLoader loader, String[] classNames)
047: throws ClassNotFoundException {
048: super ();
049: mTestClasses = new Class[classNames.length];
050: for (int i = 0; i < classNames.length; i++) {
051: mTestClasses[i] = loader.loadClass(classNames[i]);
052: addTestSuite(mTestClasses[i]);
053: }
054: }
055:
056: /**
057: * Runs the tests and records their runtimes. The test results are returned in
058: * <CODE>result</CODE> as usual in JUnit.
059: */
060: public void run(TestResult result) {
061: mRuntimes = new long[testCount()];
062: for (int i = 0; i < mRuntimes.length; i++) {
063: Test curTest = testAt(i);
064: if (DEBUG) {
065: System.out.println("Running initially " + curTest);
066: }
067: long before = System.currentTimeMillis();
068: curTest.run(result);
069: long after = System.currentTimeMillis();
070: mRuntimes[i] = after - before;
071: }
072: }
073:
074: public long getTotalRuntime() {
075: if (mRuntimes == null) {
076: throw new RuntimeException(
077: "Cannot call getTotalRuntime() before the tests have been run");
078: }
079: long sum = 0;
080: for (int i = 0; i < mRuntimes.length; i++) {
081: sum += mRuntimes[i];
082: }
083: return sum;
084: }
085:
086: /**
087: * Returns a test ordering
088: *
089: * @param orderByTime if the tests will be ordered according to the run time.
090: * @return the ordered tests.
091: * @throws RuntimeException if the tests have not been run yet
092: */
093: public TestOrder getOrder(boolean orderByTime) {
094: if (mRuntimes == null) {
095: throw new RuntimeException(
096: "Cannot call getOrder() before the tests have been run");
097: }
098: if (orderByTime) {
099: return new TestOrder(mTestClasses, mRuntimes);
100: } else {
101: return new TestOrder(mTestClasses);
102: }
103: }
104: }
|