1 | /* |
2 | * JTiger Unit Testing Framework for J2SE 1.5 |
3 | * Copyright (C) 2005 Tony Morris |
4 | * |
5 | * This software is licenced under the |
6 | * Common Public Licence version 1.0 |
7 | * http://www.opensource.org/licenses/cpl1.0.php |
8 | * |
9 | * You received a copy of this licence with this software. |
10 | */ |
11 | package org.jtiger.framework; |
12 | |
13 | import java.lang.reflect.InvocationTargetException; |
14 | import static org.jtiger.framework.ArgsConverterFactory.newArgsToFixtureRunnerParams; |
15 | import static org.jtiger.framework.ClassConstructionFactory.newClassConstruction; |
16 | import static org.jtiger.framework.TestFailureFactory.newTestFailure; |
17 | import static org.jtiger.framework.DefaultFixtureResultsHandlerFactory.newDefaultFixtureResultsHandler; |
18 | |
19 | /** |
20 | * Provides an entry point into a test execution by using a <code>main</code> method. |
21 | * The main method creates a {@link FixturesRunnerConfig} from the command line arguments then delegates to a |
22 | * {@link FixturesRunner} instance, which is created by a {@link FixturesRunnerFactory}. |
23 | * |
24 | * @author %javadoc.author.tag% |
25 | * @version %version%<br/> |
26 | * <i>Build Number %build.number%</i><br/> |
27 | * <i>Build Time %build.time% CET (GMT + 1)</i> |
28 | */ |
29 | public final class FixturesRunnerMain |
30 | { |
31 | /** |
32 | * A case-insensitive command line argument which should be followed by one or more arguments that represent the |
33 | * class names of the test fixtures to execute. By omitting this argument, no test fixtures will be executed. |
34 | * |
35 | * @see FixturesRunnerConfig#getFixtureClasses() |
36 | */ |
37 | public static final String ARG_FIXTURE_CLASSES = "-fixtureClasses"; |
38 | |
39 | /** |
40 | * A case-insensitive command line argument which should be followed by one class name argument that represents the |
41 | * test definition class. By omitting this argument, the default implementation will be used. |
42 | * This class should implement the interface {@link TestDefinition}, otherwise the default implementation is used. |
43 | * |
44 | * @see FixturesRunnerConfig#getDefinitionClass() |
45 | */ |
46 | public static final String ARG_DEFINITION_CLASS = "-definitionClass"; |
47 | |
48 | /** |
49 | * A case-insensitive command line argument which should be followed by one argument that represents the class name |
50 | * of the test fixture set up and tear down class. By omitting this argument, the default implementation will be |
51 | * used. |
52 | * This class should implement the interface {@link SetUpTearDown}, otherwise the default implementation is used. |
53 | * |
54 | * @see FixturesRunnerConfig#getSutdClass() |
55 | */ |
56 | public static final String ARG_SUTD_CLASS = "-sutdClass"; |
57 | |
58 | /** |
59 | * A case-insensitive command line argument which should be followed by no arguments that represents that a test |
60 | * execution will be of <a href="%junit.url%" target="_blank">JUnit</a> test cases. Specifying this argument |
61 | * overrides any value that is set for the {@link #ARG_DEFINITION_CLASS} or {@link #ARG_SUTD_CLASS} arguments. |
62 | */ |
63 | public static final String ARG_JUNIT = "-junit"; |
64 | |
65 | /** |
66 | * A case-insensitive command line argument which should be followed by no arguments that represents that a test |
67 | * execution should discontinue if a failure is encountered. By omitting this argument, the default value of |
68 | * <code>false</code> will be used. |
69 | * |
70 | * @see FixturesRunnerConfig#isHaltOnFailure() |
71 | */ |
72 | public static final String ARG_HALT_ON_FAILURE = "-haltOnFailure"; |
73 | |
74 | /** |
75 | * A case-insensitive command line argument which should be followed by one or more arguments that represent the |
76 | * regular expressions of test case categories to execute. By omitting this argument, all categories will be |
77 | * executed. |
78 | * |
79 | * @see FixturesRunnerConfig#getCategories() |
80 | */ |
81 | public static final String ARG_CATEGORIES = "-categories"; |
82 | |
83 | /** |
84 | * A case-insensitive command line argument which should be followed by one argument that represents the class name |
85 | * of the test fixture result handler. |
86 | * This class should implement the interface {@link FixtureResultsHandler}, otherwise the default implementation is |
87 | * used. |
88 | */ |
89 | public static final String ARG_RESULT = "-result"; |
90 | |
91 | /** |
92 | * A case-insensitive command line argument which should be followed by one or more arguments that represent the |
93 | * parameters to be passed to the test fixture result handler. |
94 | */ |
95 | public static final String ARG_RESULT_PARAMETERS = "-resultParams"; |
96 | |
97 | /** |
98 | * The return code of the Java Virtual Machine if the command line arguments are in an incorrect format. |
99 | * This includes passing no command line arguments. |
100 | */ |
101 | public static final int RC_WRONG_USAGE = 1; |
102 | |
103 | /** |
104 | * The return code of the Java Virtual Machine if {@link #ARG_HALT_ON_FAILURE} is used and a test case failure |
105 | * occurs. |
106 | */ |
107 | public static final int RC_HALTED_ON_FAILURE = 2; |
108 | |
109 | private FixturesRunnerMain() |
110 | { |
111 | |
112 | } |
113 | |
114 | /** |
115 | * Returns <code>true</code> if the given arguments can be used to execute {@link #main(String[]) main method} |
116 | * successfully, <code>false</code> otherwise. |
117 | * |
118 | * @param args The arguments to test for a correct format for execution by the {@link #main(String[]) main method}. |
119 | * @return <code>true</code> if the given arguments can be used to execute {@link #main(String[]) main method} |
120 | * successfully, <code>false</code> otherwise. |
121 | * @throws ClassNotFoundException If the passed class names in the command line arguments cannot be loaded. |
122 | */ |
123 | public static boolean isCorrectFormat(final String... args) throws ClassNotFoundException |
124 | { |
125 | return args != null && args.length > 0 && newArgsToFixtureRunnerParams().convert(args) != null; |
126 | } |
127 | |
128 | /** |
129 | * Execute the test run with the given command line arguments. |
130 | * This method will cause a forced JVM shut down by calling |
131 | * <a href="%j2se.api.spec/java/lang/System#exit(int)">System.exit</a> only if the passed command line arguments are |
132 | * not in a correct format (or not present at all) or if {@link #ARG_HALT_ON_FAILURE} has been set and a test |
133 | * failure occurs. It is guaranteed that if {@link #isCorrectFormat(String[])} returns <code>true</code> and if |
134 | * {@link #ARG_HALT_ON_FAILURE} is not passed, that a forced JVM shut down will not occur. |
135 | * Compile-time checked exceptions, which may be thrown during test execution, will be handled by outputting them to |
136 | * the <a href="%j2se.api.spec%/java/lang/System.html#err">standard error stream</a>. |
137 | * |
138 | * @param args The arguments to execute the test run with. |
139 | */ |
140 | public static void main(final String... args) |
141 | { |
142 | if(args.length == 0) |
143 | { |
144 | usage(); |
145 | |
146 | System.exit(RC_WRONG_USAGE); |
147 | } |
148 | |
149 | try |
150 | { |
151 | final Args a = newArgsToFixtureRunnerParams().convert(args); |
152 | |
153 | if(a == null) |
154 | { |
155 | usage(); |
156 | |
157 | System.exit(RC_WRONG_USAGE); |
158 | } |
159 | else |
160 | { |
161 | final FixturesRunner runner = FixturesRunnerFactory.newFixturesRunner(); |
162 | final FixturesRunnerConfig config = a.getFixturesRunnerConfig(); |
163 | final FixtureResults results = runner.run(config); |
164 | |
165 | if(config.isHaltOnFailure()) |
166 | { |
167 | final TestFailure tf = newTestFailure(); |
168 | |
169 | for(FixtureResult result : results) |
170 | { |
171 | for(TestResult tr : result) |
172 | { |
173 | if(tf.isFailure(tr.getTestResultType())) |
174 | { |
175 | System.exit(RC_HALTED_ON_FAILURE); |
176 | } |
177 | } |
178 | } |
179 | } |
180 | |
181 | final ClassConstruction construction = newClassConstruction(); |
182 | FixtureResultsHandler rh = construction.construct(a.getResultHandlerClass()); |
183 | |
184 | if(rh == null) |
185 | { |
186 | rh = newDefaultFixtureResultsHandler(); |
187 | } |
188 | |
189 | rh.handleResult(results, a.getResultHandlerParameters()); |
190 | } |
191 | } |
192 | catch(FixtureResultsHandlerException e) |
193 | { |
194 | System.err.println(e); |
195 | } |
196 | catch(ClassNotFoundException e) |
197 | { |
198 | System.err.println(e); |
199 | } |
200 | catch(IllegalAccessException e) |
201 | { |
202 | System.err.println(e); |
203 | } |
204 | catch(InstantiationException e) |
205 | { |
206 | System.err.println(e); |
207 | } |
208 | catch(InvocationTargetException e) |
209 | { |
210 | System.err.println(e); |
211 | } |
212 | catch(RunnerException e) |
213 | { |
214 | System.err.println(e); |
215 | } |
216 | } |
217 | |
218 | /** |
219 | * Prints usage information to the <a href="%j2se.api.spec%/java/lang/System.html#err">standard error stream</a>. |
220 | */ |
221 | public static void usage() |
222 | { |
223 | System.err.println(Messages.usage()); |
224 | } |
225 | } |