View Javadoc
1   package org.junit.runner;
2   
3   import java.util.Comparator;
4   
5   import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
6   import org.junit.internal.requests.ClassRequest;
7   import org.junit.internal.requests.FilterRequest;
8   import org.junit.internal.requests.SortingRequest;
9   import org.junit.internal.runners.ErrorReportingRunner;
10  import org.junit.runner.manipulation.Filter;
11  import org.junit.runners.model.InitializationError;
12  
13  /**
14   * A <code>Request</code> is an abstract description of tests to be run. Older versions of
15   * JUnit did not need such a concept--tests to be run were described either by classes containing
16   * tests or a tree of {@link  org.junit.Test}s. However, we want to support filtering and sorting,
17   * so we need a more abstract specification than the tests themselves and a richer
18   * specification than just the classes.
19   *
20   * <p>The flow when JUnit runs tests is that a <code>Request</code> specifies some tests to be run -&gt;
21   * a {@link org.junit.runner.Runner} is created for each class implied by the <code>Request</code> -&gt;
22   * the {@link org.junit.runner.Runner} returns a detailed {@link org.junit.runner.Description}
23   * which is a tree structure of the tests to be run.
24   *
25   * @since 4.0
26   */
27  public abstract class Request {
28      /**
29       * Create a <code>Request</code> that, when processed, will run a single test.
30       * This is done by filtering out all other tests. This method is used to support rerunning
31       * single tests.
32       *
33       * @param clazz the class of the test
34       * @param methodName the name of the test
35       * @return a <code>Request</code> that will cause a single test be run
36       */
37      public static Request method(Class<?> clazz, String methodName) {
38          Description method = Description.createTestDescription(clazz, methodName);
39          return Request.aClass(clazz).filterWith(method);
40      }
41  
42      /**
43       * Create a <code>Request</code> that, when processed, will run all the tests
44       * in a class. The odd name is necessary because <code>class</code> is a reserved word.
45       *
46       * @param clazz the class containing the tests
47       * @return a <code>Request</code> that will cause all tests in the class to be run
48       */
49      public static Request aClass(Class<?> clazz) {
50          return new ClassRequest(clazz);
51      }
52  
53      /**
54       * Create a <code>Request</code> that, when processed, will run all the tests
55       * in a class. If the class has a suite() method, it will be ignored.
56       *
57       * @param clazz the class containing the tests
58       * @return a <code>Request</code> that will cause all tests in the class to be run
59       */
60      public static Request classWithoutSuiteMethod(Class<?> clazz) {
61          return new ClassRequest(clazz, false);
62      }
63  
64      /**
65       * Create a <code>Request</code> that, when processed, will run all the tests
66       * in a set of classes.
67       *
68       * @param computer Helps construct Runners from classes
69       * @param classes the classes containing the tests
70       * @return a <code>Request</code> that will cause all tests in the classes to be run
71       */
72      public static Request classes(Computer computer, Class<?>... classes) {
73          try {
74              AllDefaultPossibilitiesBuilder builder = new AllDefaultPossibilitiesBuilder(true);
75              Runner suite = computer.getSuite(builder, classes);
76              return runner(suite);
77          } catch (InitializationError e) {
78              throw new RuntimeException(
79                      "Bug in saff's brain: Suite constructor, called as above, should always complete");
80          }
81      }
82  
83      /**
84       * Create a <code>Request</code> that, when processed, will run all the tests
85       * in a set of classes with the default <code>Computer</code>.
86       *
87       * @param classes the classes containing the tests
88       * @return a <code>Request</code> that will cause all tests in the classes to be run
89       */
90      public static Request classes(Class<?>... classes) {
91          return classes(JUnitCore.defaultComputer(), classes);
92      }
93  
94  
95      /**
96       * Creates a {@link Request} that, when processed, will report an error for the given
97       * test class with the given cause.
98       */
99      public static Request errorReport(Class<?> klass, Throwable cause) {
100         return runner(new ErrorReportingRunner(klass, cause));
101     }
102 
103     /**
104      * @param runner the runner to return
105      * @return a <code>Request</code> that will run the given runner when invoked
106      */
107     public static Request runner(final Runner runner) {
108         return new Request() {
109             @Override
110             public Runner getRunner() {
111                 return runner;
112             }
113         };
114     }
115 
116     /**
117      * Returns a {@link Runner} for this Request
118      *
119      * @return corresponding {@link Runner} for this Request
120      */
121     public abstract Runner getRunner();
122 
123     /**
124      * Returns a Request that only contains those tests that should run when
125      * <code>filter</code> is applied
126      *
127      * @param filter The {@link Filter} to apply to this Request
128      * @return the filtered Request
129      */
130     public Request filterWith(Filter filter) {
131         return new FilterRequest(this, filter);
132     }
133 
134     /**
135      * Returns a Request that only runs contains tests whose {@link Description}
136      * equals <code>desiredDescription</code>
137      *
138      * @param desiredDescription {@link Description} of those tests that should be run
139      * @return the filtered Request
140      */
141     public Request filterWith(final Description desiredDescription) {
142         return filterWith(Filter.matchMethodDescription(desiredDescription));
143     }
144 
145     /**
146      * Returns a Request whose Tests can be run in a certain order, defined by
147      * <code>comparator</code>
148      * <p>
149      * For example, here is code to run a test suite in alphabetical order:
150      * <pre>
151      * private static Comparator&lt;Description&gt; forward() {
152      * return new Comparator&lt;Description&gt;() {
153      * public int compare(Description o1, Description o2) {
154      * return o1.getDisplayName().compareTo(o2.getDisplayName());
155      * }
156      * };
157      * }
158      *
159      * public static main() {
160      * new JUnitCore().run(Request.aClass(AllTests.class).sortWith(forward()));
161      * }
162      * </pre>
163      *
164      * @param comparator definition of the order of the tests in this Request
165      * @return a Request with ordered Tests
166      */
167     public Request sortWith(Comparator<Description> comparator) {
168         return new SortingRequest(this, comparator);
169     }
170 }