001 package junit.textui; 002 003 004 import java.io.PrintStream; 005 006 import junit.framework.Test; 007 import junit.framework.TestCase; 008 import junit.framework.TestResult; 009 import junit.framework.TestSuite; 010 import junit.runner.BaseTestRunner; 011 import junit.runner.Version; 012 013 /** 014 * A command line based tool to run tests. 015 * <pre> 016 * java junit.textui.TestRunner [-wait] TestCaseClass 017 * </pre> 018 * <p> 019 * TestRunner expects the name of a TestCase class as argument. 020 * If this class defines a static <code>suite</code> method it 021 * will be invoked and the returned test is run. Otherwise all 022 * the methods starting with "test" having no arguments are run. 023 * <p> 024 * When the wait command line argument is given TestRunner 025 * waits until the users types RETURN. 026 * <p> 027 * TestRunner prints a trace as the tests are executed followed by a 028 * summary at the end. 029 */ 030 public class TestRunner extends BaseTestRunner { 031 private ResultPrinter fPrinter; 032 033 public static final int SUCCESS_EXIT = 0; 034 public static final int FAILURE_EXIT = 1; 035 public static final int EXCEPTION_EXIT = 2; 036 037 /** 038 * Constructs a TestRunner. 039 */ 040 public TestRunner() { 041 this(System.out); 042 } 043 044 /** 045 * Constructs a TestRunner using the given stream for all the output 046 */ 047 public TestRunner(PrintStream writer) { 048 this(new ResultPrinter(writer)); 049 } 050 051 /** 052 * Constructs a TestRunner using the given ResultPrinter all the output 053 */ 054 public TestRunner(ResultPrinter printer) { 055 fPrinter = printer; 056 } 057 058 /** 059 * Runs a suite extracted from a TestCase subclass. 060 */ 061 static public void run(Class<? extends TestCase> testClass) { 062 run(new TestSuite(testClass)); 063 } 064 065 /** 066 * Runs a single test and collects its results. 067 * This method can be used to start a test run 068 * from your program. 069 * <pre> 070 * public static void main (String[] args) { 071 * test.textui.TestRunner.run(suite()); 072 * } 073 * </pre> 074 */ 075 static public TestResult run(Test test) { 076 TestRunner runner = new TestRunner(); 077 return runner.doRun(test); 078 } 079 080 /** 081 * Runs a single test and waits until the user 082 * types RETURN. 083 */ 084 static public void runAndWait(Test suite) { 085 TestRunner aTestRunner = new TestRunner(); 086 aTestRunner.doRun(suite, true); 087 } 088 089 @Override 090 public void testFailed(int status, Test test, Throwable e) { 091 } 092 093 @Override 094 public void testStarted(String testName) { 095 } 096 097 @Override 098 public void testEnded(String testName) { 099 } 100 101 /** 102 * Creates the TestResult to be used for the test run. 103 */ 104 protected TestResult createTestResult() { 105 return new TestResult(); 106 } 107 108 public TestResult doRun(Test test) { 109 return doRun(test, false); 110 } 111 112 public TestResult doRun(Test suite, boolean wait) { 113 TestResult result = createTestResult(); 114 result.addListener(fPrinter); 115 long startTime = System.currentTimeMillis(); 116 suite.run(result); 117 long endTime = System.currentTimeMillis(); 118 long runTime = endTime - startTime; 119 fPrinter.print(result, runTime); 120 121 pause(wait); 122 return result; 123 } 124 125 protected void pause(boolean wait) { 126 if (!wait) return; 127 fPrinter.printWaitPrompt(); 128 try { 129 System.in.read(); 130 } catch (Exception e) { 131 } 132 } 133 134 public static void main(String[] args) { 135 TestRunner aTestRunner = new TestRunner(); 136 try { 137 TestResult r = aTestRunner.start(args); 138 if (!r.wasSuccessful()) { 139 System.exit(FAILURE_EXIT); 140 } 141 System.exit(SUCCESS_EXIT); 142 } catch (Exception e) { 143 System.err.println(e.getMessage()); 144 System.exit(EXCEPTION_EXIT); 145 } 146 } 147 148 /** 149 * Starts a test run. Analyzes the command line arguments and runs the given 150 * test suite. 151 */ 152 public TestResult start(String[] args) throws Exception { 153 String testCase = ""; 154 String method = ""; 155 boolean wait = false; 156 157 for (int i = 0; i < args.length; i++) { 158 if (args[i].equals("-wait")) { 159 wait = true; 160 } else if (args[i].equals("-c")) { 161 testCase = extractClassName(args[++i]); 162 } else if (args[i].equals("-m")) { 163 String arg = args[++i]; 164 int lastIndex = arg.lastIndexOf('.'); 165 testCase = arg.substring(0, lastIndex); 166 method = arg.substring(lastIndex + 1); 167 } else if (args[i].equals("-v")) { 168 System.err.println("JUnit " + Version.id() + " by Kent Beck and Erich Gamma"); 169 } else { 170 testCase = args[i]; 171 } 172 } 173 174 if (testCase.equals("")) { 175 throw new Exception("Usage: TestRunner [-wait] testCaseName, where name is the name of the TestCase class"); 176 } 177 178 try { 179 if (!method.equals("")) { 180 return runSingleMethod(testCase, method, wait); 181 } 182 Test suite = getTest(testCase); 183 return doRun(suite, wait); 184 } catch (Exception e) { 185 throw new Exception("Could not create and run test suite: " + e); 186 } 187 } 188 189 protected TestResult runSingleMethod(String testCase, String method, boolean wait) throws Exception { 190 Class<? extends TestCase> testClass = loadSuiteClass(testCase).asSubclass(TestCase.class); 191 Test test = TestSuite.createTest(testClass, method); 192 return doRun(test, wait); 193 } 194 195 @Override 196 protected void runFailed(String message) { 197 System.err.println(message); 198 System.exit(FAILURE_EXIT); 199 } 200 201 public void setPrinter(ResultPrinter printer) { 202 fPrinter = printer; 203 } 204 205 206 }