View Javadoc
1   package junit.textui;
2   
3   
4   import java.io.PrintStream;
5   
6   import junit.framework.Test;
7   import junit.framework.TestCase;
8   import junit.framework.TestResult;
9   import junit.framework.TestSuite;
10  import junit.runner.BaseTestRunner;
11  import junit.runner.Version;
12  
13  /**
14   * A command line based tool to run tests.
15   * <pre>
16   * java junit.textui.TestRunner [-wait] TestCaseClass
17   * </pre>
18   * <p>
19   * TestRunner expects the name of a TestCase class as argument.
20   * If this class defines a static <code>suite</code> method it
21   * will be invoked and the returned test is run. Otherwise all
22   * the methods starting with "test" having no arguments are run.
23   * <p>
24   * When the wait command line argument is given TestRunner
25   * waits until the users types RETURN.
26   * <p>
27   * TestRunner prints a trace as the tests are executed followed by a
28   * summary at the end.
29   */
30  public class TestRunner extends BaseTestRunner {
31      private ResultPrinter fPrinter;
32  
33      public static final int SUCCESS_EXIT = 0;
34      public static final int FAILURE_EXIT = 1;
35      public static final int EXCEPTION_EXIT = 2;
36  
37      /**
38       * Constructs a TestRunner.
39       */
40      public TestRunner() {
41          this(System.out);
42      }
43  
44      /**
45       * Constructs a TestRunner using the given stream for all the output
46       */
47      public TestRunner(PrintStream writer) {
48          this(new ResultPrinter(writer));
49      }
50  
51      /**
52       * Constructs a TestRunner using the given ResultPrinter all the output
53       */
54      public TestRunner(ResultPrinter printer) {
55          fPrinter = printer;
56      }
57  
58      /**
59       * Runs a suite extracted from a TestCase subclass.
60       */
61      static public void run(Class<? extends TestCase> testClass) {
62          run(new TestSuite(testClass));
63      }
64  
65      /**
66       * Runs a single test and collects its results.
67       * This method can be used to start a test run
68       * from your program.
69       * <pre>
70       * public static void main (String[] args) {
71       *    test.textui.TestRunner.run(suite());
72       * }
73       * </pre>
74       */
75      static public TestResult run(Test test) {
76          TestRunner runner = new TestRunner();
77          return runner.doRun(test);
78      }
79  
80      /**
81       * Runs a single test and waits until the user
82       * types RETURN.
83       */
84      static public void runAndWait(Test suite) {
85          TestRunner aTestRunner = new TestRunner();
86          aTestRunner.doRun(suite, true);
87      }
88  
89      @Override
90      public void testFailed(int status, Test test, Throwable e) {
91      }
92  
93      @Override
94      public void testStarted(String testName) {
95      }
96  
97      @Override
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         } 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 }