ba4e81de22262f23a8e9161c2b2b81fec4413c15
1 package be
.nikiroo
.utils
.test
;
3 import java
.util
.ArrayList
;
7 * A {@link TestLauncher} starts a series of {@link TestCase}s and displays the
12 public class TestLauncher
{
14 * {@link Exception} happening during the setup process.
18 private class SetupException
extends Exception
{
19 private static final long serialVersionUID
= 1L;
21 public SetupException(Exception e
) {
27 * {@link Exception} happening during the tear-down process.
31 private class TearDownException
extends Exception
{
32 private static final long serialVersionUID
= 1L;
34 public TearDownException(Exception e
) {
39 private List
<TestLauncher
> series
;
40 private List
<TestCase
> tests
;
42 private String okString
;
43 private String koString
;
47 protected int executed
;
51 * Create a new {@link TestLauncher} with default parameters.
56 * the arguments to configure the number of columns and the ok/ko
59 public TestLauncher(String name
, String
[] args
) {
63 if (args
!= null && args
.length
>= 1) {
65 cols
= Integer
.parseInt(args
[0]);
66 } catch (NumberFormatException e
) {
67 System
.err
.println("Test configuration: given number "
68 + "of columns is not parseable: " + args
[0]);
74 String okString
= "[ ok ]";
75 String koString
= "[ !! ]";
76 if (args
!= null && args
.length
>= 3) {
81 setOkString(okString
);
82 setKoString(koString
);
84 series
= new ArrayList
<TestLauncher
>();
85 tests
= new ArrayList
<TestCase
>();
90 * Called before actually starting the tests themselves.
95 protected void start() throws Exception
{
99 * Called when the tests are passed (or failed to do so).
104 protected void stop() throws Exception
{
107 protected void addTest(TestCase test
) {
111 protected void addSeries(TestLauncher series
) {
112 this.series
.add(series
);
116 * Launch the series of {@link TestCase}s and the {@link TestCase}s.
118 * @return the number of errors
120 public int launch() {
125 * Launch the series of {@link TestCase}s and the {@link TestCase}s.
128 * the level at which is the launcher (0 = main launcher)
130 * @return the number of errors
132 public int launch(int depth
) {
135 total
= tests
.size();
142 errors
+= launchTests(depth
);
143 if (tests
.size() > 0 && depth
== 0) {
144 System
.out
.println("");
147 for (TestLauncher serie
: series
) {
148 errors
+= serie
.launch(depth
+ 1);
149 executed
+= serie
.executed
;
150 total
+= serie
.total
;
152 } catch (Exception e
) {
153 print(depth
, "__start");
158 } catch (Exception e
) {
159 print(depth
, "__stop");
164 print(depth
, executed
, errors
, total
);
170 * Launch the {@link TestCase}s.
173 * the level at which is the launcher (0 = main launcher)
175 * @return the number of errors
177 protected int launchTests(int depth
) {
179 for (TestCase test
: tests
) {
180 print(depth
, test
.getName());
186 } catch (Exception e
) {
187 throw new SetupException(e
);
192 } catch (Exception e
) {
193 throw new TearDownException(e
);
195 } catch (Exception e
) {
207 if (ex
!= null && !cont
) {
216 * Specify a custom number of columns to use for the display of messages.
219 * the number of columns
221 public void setColumns(int columns
) {
222 this.columns
= columns
;
226 * Continue to run the tests when an error is detected.
231 public void setContinueAfterFail(boolean cont
) {
236 * Set a custom "[ ok ]" {@link String} when a test passed.
239 * the {@link String} to display at the end of a success
241 public void setOkString(String okString
) {
242 this.okString
= okString
;
246 * Set a custom "[ !! ]" {@link String} when a test failed.
249 * the {@link String} to display at the end of a failure
251 public void setKoString(String koString
) {
252 this.koString
= koString
;
256 * Print the test suite header.
259 * the level at which is the launcher (0 = main launcher)
261 protected void print(int depth
) {
263 System
.out
.println("[ Test suite: " + name
+ " ]");
264 System
.out
.println("");
266 System
.out
.println(prefix(depth
) + name
+ ":");
271 * Print the name of the {@link TestCase} we will start immediately after.
274 * the level at which is the launcher (0 = main launcher)
276 * the {@link TestCase}
278 protected void print(int depth
, String name
) {
279 name
= prefix(depth
) + (name
== null ?
"" : name
).replace("\t", " ");
281 while (name
.length() < columns
- 11) {
285 System
.out
.print(name
);
289 * Print the result of the {@link TestCase} we just ran.
292 * the level at which is the launcher (0 = main launcher)
294 * the {@link Exception} it ran into if any
296 private void print(int depth
, Exception error
) {
298 System
.out
.println(" " + koString
);
299 for (String line
: (error
.getMessage() + "").split("\n")) {
300 System
.out
.println(prefix(depth
) + "\t\t" + line
);
303 System
.out
.println(" " + okString
);
308 * Print the total result for this test suite.
311 * the level at which is the launcher (0 = main launcher)
313 * the number of tests actually ran
315 * the number of errors encountered
317 * the total number of tests in the suite
319 private void print(int depth
, int executed
, int errors
, int total
) {
320 int ok
= executed
- errors
;
321 int pc
= (int) ((100.0 * ok
) / executed
);
322 if (pc
== 0 && ok
> 0) {
325 int pcTotal
= (int) ((100.0 * ok
) / total
);
326 if (pcTotal
== 0 && ok
> 0) {
330 String resume
= "Tests passed: " + ok
+ "/" + executed
+ " (" + pc
331 + "%) on a total of " + total
+ " (" + pcTotal
+ "% total)";
333 System
.out
.println(resume
);
336 if (series
.isEmpty()) {
339 System
.out
.println(prefix(depth
) + arrow
+ resume
);
343 private int last
= -1;
346 * Return the prefix to print before the current line.
353 private String
prefix(int depth
) {
354 String space
= tabs(depth
- 1);
360 line
= "╻"; // first line
362 line
= "┃"; // continuation
365 space
= space
+ line
+ tabs(1);
373 * Return the given number of space-converted tabs in a {@link String}.
376 * the number of tabs to return
380 private String
tabs(int depth
) {
382 StringBuilder builder
= new StringBuilder();
383 for (int i
= 0; i
< depth
; i
++) {
386 return builder
.toString();