1   package junit.textui;
2   
3   
4   import java.io.PrintStream;
5   
6   import junit.framework.*;
7   import junit.runner.*;
8   
9   /***
10   * A command line based tool to run tests.
11   * <pre>
12   * java junit.textui.TestRunner [-wait] TestCaseClass
13   * </pre>
14   * TestRunner expects the name of a TestCase class as argument.
15   * If this class defines a static <code>suite</code> method it 
16   * will be invoked and the returned test is run. Otherwise all 
17   * the methods starting with "test" having no arguments are run.
18   * <p>
19   * When the wait command line argument is given TestRunner
20   * waits until the users types RETURN.
21   * <p>
22   * TestRunner prints a trace as the tests are executed followed by a
23   * summary at the end. 
24   */
25  public class TestRunner extends BaseTestRunner {
26  	private ResultPrinter fPrinter;
27  	
28  	public static final int SUCCESS_EXIT= 0;
29  	public static final int FAILURE_EXIT= 1;
30  	public static final int EXCEPTION_EXIT= 2;
31  
32  	/***
33  	 * Constructs a TestRunner.
34  	 */
35  	public TestRunner() {
36  		this(System.out);
37  	}
38  
39  	/***
40  	 * Constructs a TestRunner using the given stream for all the output
41  	 */
42  	public TestRunner(PrintStream writer) {
43  		this(new ResultPrinter(writer));
44  	}
45  	
46  	/***
47  	 * Constructs a TestRunner using the given ResultPrinter all the output
48  	 */
49  	public TestRunner(ResultPrinter printer) {
50  		fPrinter= printer;
51  	}
52  	
53  	/***
54  	 * Runs a suite extracted from a TestCase subclass.
55  	 */
56  	static public void run(Class testClass) {
57  		run(new TestSuite(testClass));
58  	}
59  
60  	/***
61  	 * Runs a single test and collects its results.
62  	 * This method can be used to start a test run
63  	 * from your program.
64  	 * <pre>
65  	 * public static void main (String[] args) {
66  	 *     test.textui.TestRunner.run(suite());
67  	 * }
68  	 * </pre>
69  	 */
70  	static public TestResult run(Test test) {
71  		TestRunner runner= new TestRunner();
72  		return runner.doRun(test);
73  	}
74  
75  	/***
76  	 * Runs a single test and waits until the user
77  	 * types RETURN.
78  	 */
79  	static public void runAndWait(Test suite) {
80  		TestRunner aTestRunner= new TestRunner();
81  		aTestRunner.doRun(suite, true);
82  	}
83  
84  	/***
85  	 * Always use the StandardTestSuiteLoader. Overridden from
86  	 * BaseTestRunner.
87  	 */
88  	public TestSuiteLoader getLoader() {
89  		return new StandardTestSuiteLoader();
90  	}
91  
92  	public void testFailed(int status, Test test, Throwable t) {
93  	}
94  	
95  	public void testStarted(String testName) {
96  	}
97  	
98  	public void testEnded(String testName) {
99  	}
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 		}
131 		catch(Exception e) {
132 		}
133 	}
134 	
135 	public static void main(String args[]) {
136 		TestRunner aTestRunner= new TestRunner();
137 		try {
138 			TestResult r= aTestRunner.start(args);
139 			if (!r.wasSuccessful()) 
140 				System.exit(FAILURE_EXIT);
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
150 	 * and runs the given test suite.
151 	 */
152 	protected TestResult start(String args[]) throws Exception {
153 		String testCase= "";
154 		boolean wait= false;
155 		
156 		for (int i= 0; i < args.length; i++) {
157 			if (args[i].equals("-wait"))
158 				wait= true;
159 			else if (args[i].equals("-c")) 
160 				testCase= extractClassName(args[++i]);
161 			else if (args[i].equals("-v"))
162 				System.err.println("JUnit "+Version.id()+" by Kent Beck and Erich Gamma");
163 			else
164 				testCase= args[i];
165 		}
166 		
167 		if (testCase.equals("")) 
168 			throw new Exception("Usage: TestRunner [-wait] testCaseName, where name is the name of the TestCase class");
169 
170 		try {
171 			Test suite= getTest(testCase);
172 			return doRun(suite, wait);
173 		}
174 		catch(Exception e) {
175 			throw new Exception("Could not create and run test suite: "+e);
176 		}
177 	}
178 		
179 	protected void runFailed(String message) {
180 		System.err.println(message);
181 		System.exit(FAILURE_EXIT);
182 	}
183 	
184 	public void setPrinter(ResultPrinter printer) {
185 		fPrinter= printer;
186 	}
187 		
188 	
189 }