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 }