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.OrderingRequest; 9 import org.junit.internal.requests.SortingRequest; 10 import org.junit.internal.runners.ErrorReportingRunner; 11 import org.junit.runner.manipulation.Filter; 12 import org.junit.runner.manipulation.Ordering; 13 import org.junit.runners.model.InitializationError; 14 15 /** 16 * A <code>Request</code> is an abstract description of tests to be run. Older versions of 17 * JUnit did not need such a concept--tests to be run were described either by classes containing 18 * tests or a tree of {@link org.junit.Test}s. However, we want to support filtering and sorting, 19 * so we need a more abstract specification than the tests themselves and a richer 20 * specification than just the classes. 21 * 22 * <p>The flow when JUnit runs tests is that a <code>Request</code> specifies some tests to be run -> 23 * a {@link org.junit.runner.Runner} is created for each class implied by the <code>Request</code> -> 24 * the {@link org.junit.runner.Runner} returns a detailed {@link org.junit.runner.Description} 25 * which is a tree structure of the tests to be run. 26 * 27 * @since 4.0 28 */ 29 public abstract class Request { 30 /** 31 * Create a <code>Request</code> that, when processed, will run a single test. 32 * This is done by filtering out all other tests. This method is used to support rerunning 33 * single tests. 34 * 35 * @param clazz the class of the test 36 * @param methodName the name of the test 37 * @return a <code>Request</code> that will cause a single test be run 38 */ method(Class<?> clazz, String methodName)39 public static Request method(Class<?> clazz, String methodName) { 40 Description method = Description.createTestDescription(clazz, methodName); 41 return Request.aClass(clazz).filterWith(method); 42 } 43 44 /** 45 * Create a <code>Request</code> that, when processed, will run all the tests 46 * in a class. The odd name is necessary because <code>class</code> is a reserved word. 47 * 48 * @param clazz the class containing the tests 49 * @return a <code>Request</code> that will cause all tests in the class to be run 50 */ aClass(Class<?> clazz)51 public static Request aClass(Class<?> clazz) { 52 return new ClassRequest(clazz); 53 } 54 55 /** 56 * Create a <code>Request</code> that, when processed, will run all the tests 57 * in a class. If the class has a suite() method, it will be ignored. 58 * 59 * @param clazz the class containing the tests 60 * @return a <code>Request</code> that will cause all tests in the class to be run 61 */ classWithoutSuiteMethod(Class<?> clazz)62 public static Request classWithoutSuiteMethod(Class<?> clazz) { 63 return new ClassRequest(clazz, false); 64 } 65 66 /** 67 * Create a <code>Request</code> that, when processed, will run all the tests 68 * in a set of classes. 69 * 70 * @param computer Helps construct Runners from classes 71 * @param classes the classes containing the tests 72 * @return a <code>Request</code> that will cause all tests in the classes to be run 73 */ classes(Computer computer, Class<?>... classes)74 public static Request classes(Computer computer, Class<?>... classes) { 75 try { 76 AllDefaultPossibilitiesBuilder builder = new AllDefaultPossibilitiesBuilder(); 77 Runner suite = computer.getSuite(builder, classes); 78 return runner(suite); 79 } catch (InitializationError e) { 80 return runner(new ErrorReportingRunner(e, classes)); 81 } 82 } 83 84 /** 85 * Create a <code>Request</code> that, when processed, will run all the tests 86 * in a set of classes with the default <code>Computer</code>. 87 * 88 * @param classes the classes containing the tests 89 * @return a <code>Request</code> that will cause all tests in the classes to be run 90 */ classes(Class<?>.... classes)91 public static Request classes(Class<?>... classes) { 92 return classes(JUnitCore.defaultComputer(), classes); 93 } 94 95 96 /** 97 * Creates a {@link Request} that, when processed, will report an error for the given 98 * test class with the given cause. 99 */ errorReport(Class<?> klass, Throwable cause)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 */ runner(final Runner runner)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 } 203