001 package org.junit.runner;
002
003 import java.util.Comparator;
004
005 import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
006 import org.junit.internal.requests.ClassRequest;
007 import org.junit.internal.requests.FilterRequest;
008 import org.junit.internal.requests.OrderingRequest;
009 import org.junit.internal.requests.SortingRequest;
010 import org.junit.internal.runners.ErrorReportingRunner;
011 import org.junit.runner.manipulation.Filter;
012 import org.junit.runner.manipulation.Ordering;
013 import org.junit.runners.model.InitializationError;
014
015 /**
016 * A <code>Request</code> is an abstract description of tests to be run. Older versions of
017 * JUnit did not need such a concept--tests to be run were described either by classes containing
018 * tests or a tree of {@link org.junit.Test}s. However, we want to support filtering and sorting,
019 * so we need a more abstract specification than the tests themselves and a richer
020 * specification than just the classes.
021 *
022 * <p>The flow when JUnit runs tests is that a <code>Request</code> specifies some tests to be run ->
023 * a {@link org.junit.runner.Runner} is created for each class implied by the <code>Request</code> ->
024 * the {@link org.junit.runner.Runner} returns a detailed {@link org.junit.runner.Description}
025 * which is a tree structure of the tests to be run.
026 *
027 * @since 4.0
028 */
029 public abstract class Request {
030 /**
031 * Create a <code>Request</code> that, when processed, will run a single test.
032 * This is done by filtering out all other tests. This method is used to support rerunning
033 * single tests.
034 *
035 * @param clazz the class of the test
036 * @param methodName the name of the test
037 * @return a <code>Request</code> that will cause a single test be run
038 */
039 public static Request method(Class<?> clazz, String methodName) {
040 Description method = Description.createTestDescription(clazz, methodName);
041 return Request.aClass(clazz).filterWith(method);
042 }
043
044 /**
045 * Create a <code>Request</code> that, when processed, will run all the tests
046 * in a class. The odd name is necessary because <code>class</code> is a reserved word.
047 *
048 * @param clazz the class containing the tests
049 * @return a <code>Request</code> that will cause all tests in the class to be run
050 */
051 public static Request aClass(Class<?> clazz) {
052 return new ClassRequest(clazz);
053 }
054
055 /**
056 * Create a <code>Request</code> that, when processed, will run all the tests
057 * in a class. If the class has a suite() method, it will be ignored.
058 *
059 * @param clazz the class containing the tests
060 * @return a <code>Request</code> that will cause all tests in the class to be run
061 */
062 public static Request classWithoutSuiteMethod(Class<?> clazz) {
063 return new ClassRequest(clazz, false);
064 }
065
066 /**
067 * Create a <code>Request</code> that, when processed, will run all the tests
068 * in a set of classes.
069 *
070 * @param computer Helps construct Runners from classes
071 * @param classes the classes containing the tests
072 * @return a <code>Request</code> that will cause all tests in the classes to be run
073 */
074 public static Request classes(Computer computer, Class<?>... classes) {
075 try {
076 AllDefaultPossibilitiesBuilder builder = new AllDefaultPossibilitiesBuilder();
077 Runner suite = computer.getSuite(builder, classes);
078 return runner(suite);
079 } catch (InitializationError e) {
080 return runner(new ErrorReportingRunner(e, classes));
081 }
082 }
083
084 /**
085 * Create a <code>Request</code> that, when processed, will run all the tests
086 * in a set of classes with the default <code>Computer</code>.
087 *
088 * @param classes the classes containing the tests
089 * @return a <code>Request</code> that will cause all tests in the classes to be run
090 */
091 public static Request classes(Class<?>... classes) {
092 return classes(JUnitCore.defaultComputer(), classes);
093 }
094
095
096 /**
097 * Creates a {@link Request} that, when processed, will report an error for the given
098 * test class with the given cause.
099 */
100 public static Request errorReport(Class<?> klass, Throwable cause) {
101 return runner(new ErrorReportingRunner(klass, cause));
102 }
103
104 /**
105 * @param runner the runner to return
106 * @return a <code>Request</code> that will run the given runner when invoked
107 */
108 public static Request runner(final Runner runner) {
109 return new Request() {
110 @Override
111 public Runner getRunner() {
112 return runner;
113 }
114 };
115 }
116
117 /**
118 * Returns a {@link Runner} for this Request
119 *
120 * @return corresponding {@link Runner} for this Request
121 */
122 public abstract Runner getRunner();
123
124 /**
125 * Returns a Request that only contains those tests that should run when
126 * <code>filter</code> is applied
127 *
128 * @param filter The {@link Filter} to apply to this Request
129 * @return the filtered Request
130 */
131 public Request filterWith(Filter filter) {
132 return new FilterRequest(this, filter);
133 }
134
135 /**
136 * Returns a Request that only runs tests whose {@link Description}
137 * matches the given description.
138 *
139 * <p>Returns an empty {@code Request} if {@code desiredDescription} is not a single test and filters all but the single
140 * test if {@code desiredDescription} is a single test.</p>
141 *
142 * @param desiredDescription {@code Description} of those tests that should be run
143 * @return the filtered Request
144 */
145 public Request filterWith(Description desiredDescription) {
146 return filterWith(Filter.matchMethodDescription(desiredDescription));
147 }
148
149 /**
150 * Returns a Request whose Tests can be run in a certain order, defined by
151 * <code>comparator</code>
152 * <p>
153 * For example, here is code to run a test suite in alphabetical order:
154 * <pre>
155 * private static Comparator<Description> forward() {
156 * return new Comparator<Description>() {
157 * public int compare(Description o1, Description o2) {
158 * return o1.getDisplayName().compareTo(o2.getDisplayName());
159 * }
160 * };
161 * }
162 *
163 * public static main() {
164 * new JUnitCore().run(Request.aClass(AllTests.class).sortWith(forward()));
165 * }
166 * </pre>
167 *
168 * @param comparator definition of the order of the tests in this Request
169 * @return a Request with ordered Tests
170 */
171 public Request sortWith(Comparator<Description> comparator) {
172 return new SortingRequest(this, comparator);
173 }
174
175 /**
176 * Returns a Request whose Tests can be run in a certain order, defined by
177 * <code>ordering</code>
178 * <p>
179 * For example, here is code to run a test suite in reverse order:
180 * <pre>
181 * private static Ordering reverse() {
182 * return new Ordering() {
183 * public List<Description> orderItems(Collection<Description> descriptions) {
184 * List<Description> ordered = new ArrayList<>(descriptions);
185 * Collections.reverse(ordered);
186 * return ordered;
187 * }
188 * }
189 * }
190 *
191 * public static main() {
192 * new JUnitCore().run(Request.aClass(AllTests.class).orderWith(reverse()));
193 * }
194 * </pre>
195 *
196 * @return a Request with ordered Tests
197 * @since 4.13
198 */
199 public Request orderWith(Ordering ordering) {
200 return new OrderingRequest(this, ordering);
201 }
202 }