1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.surefire.report;
20
21 import java.io.*;
22 import java.nio.file.Files;
23 import java.nio.file.Path;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.List;
27
28 import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
29 import org.apache.maven.plugins.surefire.report.ReportTestCase.FlakyError;
30 import org.apache.maven.plugins.surefire.report.ReportTestCase.FlakyFailure;
31 import org.junit.After;
32 import org.junit.Before;
33 import org.junit.Test;
34
35 import static java.nio.charset.StandardCharsets.UTF_8;
36 import static org.hamcrest.MatcherAssert.assertThat;
37 import static org.hamcrest.Matchers.containsString;
38 import static org.hamcrest.Matchers.empty;
39 import static org.hamcrest.Matchers.is;
40 import static org.hamcrest.Matchers.startsWith;
41 import static org.junit.Assert.assertEquals;
42 import static org.junit.Assert.assertFalse;
43 import static org.junit.Assert.assertNotNull;
44 import static org.junit.Assert.assertNull;
45 import static org.junit.Assert.assertTrue;
46 import static org.junit.Assume.assumeTrue;
47
48
49
50
51 @SuppressWarnings({"checkstyle:magicnumber", "checkstyle:linelength"})
52 public class TestSuiteXmlParserTest {
53 private static final String[] LINE_PATTERNS = {"at org.apache.Test.", "at org.apache.Test$"};
54
55 private final Collection<String> loggedErrors = new ArrayList<>();
56
57 private ConsoleLogger consoleLogger;
58
59 @Before
60 public void instantiateLogger() {
61 consoleLogger = new ConsoleLogger() {
62 @Override
63 public boolean isDebugEnabled() {
64 return true;
65 }
66
67 @Override
68 public void debug(String message) {}
69
70 @Override
71 public boolean isInfoEnabled() {
72 return true;
73 }
74
75 @Override
76 public void info(String message) {}
77
78 @Override
79 public boolean isWarnEnabled() {
80 return true;
81 }
82
83 @Override
84 public void warning(String message) {
85 loggedErrors.add(message);
86 }
87
88 @Override
89 public boolean isErrorEnabled() {
90 return true;
91 }
92
93 @Override
94 public void error(String message) {
95 loggedErrors.add(message);
96 }
97
98 @Override
99 public void error(String message, Throwable t) {
100 loggedErrors.add(message);
101 }
102
103 @Override
104 public void error(Throwable t) {
105 loggedErrors.add(t.getLocalizedMessage());
106 }
107 };
108 }
109
110 @After
111 public void verifyErrorFreeLogger() {
112 assertThat(loggedErrors, is(empty()));
113 }
114
115 @Test
116 public void testParse() throws Exception {
117 TestSuiteXmlParser testSuiteXmlParser = new TestSuiteXmlParser(consoleLogger);
118 String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
119 + "<testsuite failures=\"4\" time=\"0.00005\" errors=\"0\" skipped=\"0\" tests=\"4\" name=\"wellFormedXmlFailures.TestSurefire3\">\n"
120 + " <properties>\n"
121 + " <property name=\"java.runtime.name\" value=\"Java(TM) SE Runtime Environment\"/>\n"
122 + " <property name=\"sun.cpu.isalist\" value=\"amd64\"/>\n"
123 + " </properties>\n"
124 + " <testcase time=\"5E-3\" classname=\"wellFormedXmlFailures.TestSurefire3\" name=\"testLower\">\n"
125 + " <failure message=\"<\" type=\"junit.framework.AssertionFailedError\"><![CDATA[junit.framework.AssertionFailedError: <\n"
126 + "\tat junit.framework.Assert.fail(Assert.java:47)\n"
127 + "\tat wellFormedXmlFailures.TestSurefire3.testLower(TestSurefire3.java:30)\n"
128 + "]]></failure>\n"
129 + " </testcase>\n"
130 + " <testcase time=\"0\" classname=\"wellFormedXmlFailures.TestSurefire3\" name=\"testU0000\">\n"
131 + " <failure message=\"&0#;\" type=\"junit.framework.AssertionFailedError\">junit.framework.AssertionFailedError: \n"
132 + "\tat junit.framework.Assert.fail(Assert.java:47)\n"
133 + "\tat wellFormedXmlFailures.TestSurefire3.testU0000(TestSurefire3.java:40)\n"
134 + "</failure>\n"
135 + " </testcase>\n"
136 + " <testcase time=\"0\" classname=\"wellFormedXmlFailures.TestSurefire3\" name=\"testGreater\">\n"
137 + " <failure message=\">\" type=\"junit.framework.AssertionFailedError\">junit.framework.AssertionFailedError: >\n"
138 + "\tat junit.framework.Assert.fail(Assert.java:47)\n"
139 + "\tat wellFormedXmlFailures.TestSurefire3.testGreater(TestSurefire3.java:35)\n"
140 + "</failure>\n"
141 + " </testcase>\n"
142 + " <testcase time=\"0\" classname=\"wellFormedXmlFailures.TestSurefire3\" name=\"testQuote\">\n"
143 + " <failure message=\""\" type=\"junit.framework.AssertionFailedError\">junit.framework.AssertionFailedError: \"\n"
144 + "\tat junit.framework.Assert.fail(Assert.java:47)\n"
145 + "\tat wellFormedXmlFailures.TestSurefire3.testQuote(TestSurefire3.java:25)\n"
146 + "</failure>\n"
147 + " </testcase>\n"
148 + "</testsuite>";
149 InputStream byteArrayIs = new ByteArrayInputStream(xml.getBytes());
150 List<ReportTestSuite> parse = testSuiteXmlParser.parse(new InputStreamReader(byteArrayIs, UTF_8));
151 assertThat(parse.size(), is(1));
152 ReportTestSuite report = parse.get(0);
153 assertThat(report.getFullClassName(), is("wellFormedXmlFailures.TestSurefire3"));
154 assertThat(report.getName(), is("TestSurefire3"));
155 assertThat(report.getPackageName(), is("wellFormedXmlFailures"));
156 assertThat(report.getNumberOfTests(), is(4));
157 assertThat(report.getNumberOfSkipped(), is(0));
158 assertThat(report.getNumberOfErrors(), is(0));
159 assertThat(report.getNumberOfFailures(), is(4));
160 assertThat(report.getNumberOfFlakes(), is(0));
161 assertThat(report.getTimeElapsed(), is(0.00005f));
162 assertThat(report.getTestCases().size(), is(4));
163
164 List<ReportTestCase> tests = report.getTestCases();
165 assertThat(tests.get(0).getFullClassName(), is("wellFormedXmlFailures.TestSurefire3"));
166 assertThat(tests.get(0).getName(), is("testLower"));
167 assertThat(
168 tests.get(0).getFailureDetail(),
169 is("junit.framework.AssertionFailedError: <\n"
170 + "\tat junit.framework.Assert.fail(Assert.java:47)\n"
171 + "\tat wellFormedXmlFailures.TestSurefire3.testLower(TestSurefire3.java:30)\n"));
172 assertThat(tests.get(0).getClassName(), is("TestSurefire3"));
173 assertThat(tests.get(0).getTime(), is(0.005f));
174 assertThat(tests.get(0).getFailureErrorLine(), is("30"));
175 assertThat(tests.get(0).getFailureMessage(), is("<"));
176 assertThat(tests.get(0).getFullName(), is("wellFormedXmlFailures.TestSurefire3.testLower"));
177 assertThat(tests.get(0).getFailureType(), is("junit.framework.AssertionFailedError"));
178 assertThat(tests.get(0).hasError(), is(false));
179
180 assertThat(tests.get(1).getFullClassName(), is("wellFormedXmlFailures.TestSurefire3"));
181 assertThat(tests.get(1).getName(), is("testU0000"));
182 assertThat(
183 tests.get(1).getFailureDetail(),
184 is("junit.framework.AssertionFailedError: \n" + "\tat junit.framework.Assert.fail(Assert.java:47)\n"
185 + "\tat wellFormedXmlFailures.TestSurefire3.testU0000(TestSurefire3.java:40)\n"));
186 assertThat(tests.get(1).getClassName(), is("TestSurefire3"));
187 assertThat(tests.get(1).getTime(), is(0f));
188 assertThat(tests.get(1).getFailureErrorLine(), is("40"));
189 assertThat(tests.get(1).getFailureMessage(), is("&0#;"));
190 assertThat(tests.get(1).getFullName(), is("wellFormedXmlFailures.TestSurefire3.testU0000"));
191 assertThat(tests.get(1).getFailureType(), is("junit.framework.AssertionFailedError"));
192 assertThat(tests.get(1).hasError(), is(false));
193
194 assertThat(tests.get(2).getFullClassName(), is("wellFormedXmlFailures.TestSurefire3"));
195 assertThat(tests.get(2).getName(), is("testGreater"));
196 assertThat(
197 tests.get(2).getFailureDetail(),
198 is("junit.framework.AssertionFailedError: >\n" + "\tat junit.framework.Assert.fail(Assert.java:47)\n"
199 + "\tat wellFormedXmlFailures.TestSurefire3.testGreater(TestSurefire3.java:35)\n"));
200 assertThat(tests.get(2).getClassName(), is("TestSurefire3"));
201 assertThat(tests.get(2).getTime(), is(0f));
202 assertThat(tests.get(2).getFailureErrorLine(), is("35"));
203 assertThat(tests.get(2).getFailureMessage(), is(">"));
204 assertThat(tests.get(2).getFullName(), is("wellFormedXmlFailures.TestSurefire3.testGreater"));
205 assertThat(tests.get(2).getFailureType(), is("junit.framework.AssertionFailedError"));
206 assertThat(tests.get(2).hasError(), is(false));
207
208 assertThat(tests.get(3).getFullClassName(), is("wellFormedXmlFailures.TestSurefire3"));
209 assertThat(tests.get(3).getName(), is("testQuote"));
210 assertThat(
211 tests.get(3).getFailureDetail(),
212 is("junit.framework.AssertionFailedError: \"\n" + "\tat junit.framework.Assert.fail(Assert.java:47)\n"
213 + "\tat wellFormedXmlFailures.TestSurefire3.testQuote(TestSurefire3.java:25)\n"));
214 assertThat(tests.get(3).getClassName(), is("TestSurefire3"));
215 assertThat(tests.get(3).getTime(), is(0f));
216 assertThat(tests.get(3).getFailureErrorLine(), is("25"));
217 assertThat(tests.get(3).getFailureMessage(), is("\""));
218 assertThat(tests.get(3).getFullName(), is("wellFormedXmlFailures.TestSurefire3.testQuote"));
219 assertThat(tests.get(3).getFailureType(), is("junit.framework.AssertionFailedError"));
220 assertThat(tests.get(3).hasError(), is(false));
221 }
222
223 @Test
224 public void testParser() throws Exception {
225 TestSuiteXmlParser parser = new TestSuiteXmlParser(consoleLogger);
226
227 Collection<ReportTestSuite> oldResult = parser.parse(
228 "src/test/resources/fixture/testsuitexmlparser/TEST-org.apache.maven.surefire.test.FailingTest.xml");
229
230 assertNotNull(oldResult);
231
232 assertEquals(1, oldResult.size());
233 ReportTestSuite next = oldResult.iterator().next();
234 assertEquals(2, next.getNumberOfTests());
235 }
236
237 @Test
238 public void successfulSurefireTestReport() throws Exception {
239 TestSuiteXmlParser parser = new TestSuiteXmlParser(consoleLogger);
240 File surefireReport = new File("src/test/resources/junit-pathWithÜmlaut/TEST-umlautTest.BasicTest.xml");
241 assumeTrue(surefireReport.isFile());
242 Collection<ReportTestSuite> suites = parser.parse(surefireReport.getCanonicalPath());
243 assertNotNull(suites);
244 assertEquals(1, suites.size());
245 ReportTestSuite suite = suites.iterator().next();
246 assertThat(suite.getNumberOfTests(), is(1));
247 assertEquals(1, suite.getNumberOfTests());
248 assertEquals(0, suite.getNumberOfFlakes());
249 assertEquals(0, suite.getNumberOfFailures());
250 assertEquals(0, suite.getNumberOfErrors());
251 assertEquals(0, suite.getNumberOfSkipped());
252 assertThat(suite.getTimeElapsed(), is(0.002f));
253 assertThat(suite.getFullClassName(), is("umlautTest.BasicTest"));
254 assertThat(suite.getPackageName(), is("umlautTest"));
255 assertThat(suite.getName(), is("BasicTest"));
256 ReportTestCase test = suite.getTestCases().iterator().next();
257 assertTrue(test.isSuccessful());
258 assertNull(test.getFailureDetail());
259 assertNull(test.getFailureErrorLine());
260 assertNull(test.getFailureType());
261 assertThat(test.getTime(), is(0.002f));
262 assertThat(test.getFullClassName(), is("umlautTest.BasicTest"));
263 assertThat(test.getClassName(), is("BasicTest"));
264 assertThat(test.getName(), is("testSetUp"));
265 assertThat(test.getFullName(), is("umlautTest.BasicTest.testSetUp"));
266 }
267
268 @Test
269 public void testParserHitsFailsafeSummary() throws Exception {
270 TestSuiteXmlParser parser = new TestSuiteXmlParser(consoleLogger);
271
272 parser.parse("src/test/resources/fixture/testsuitexmlparser/failsafe-summary.xml");
273
274 assertFalse(parser.isValid());
275
276 parser.parse(
277 "src/test/resources/fixture/testsuitexmlparser/TEST-org.apache.maven.surefire.test.FailingTest.xml");
278
279 assertTrue(parser.isValid());
280 }
281
282 @Test
283 public void lastIndexOfPatternOfOrdinalTest() {
284 final StringBuilder stackTrace = new StringBuilder("\tat org.apache.Test.util(Test.java:60)\n"
285 + "\tat org.apache.Test.test(Test.java:30)\n" + "\tat com.sun.Impl.xyz(Impl.java:258)\n");
286
287 int[] result = TestSuiteXmlParser.lastIndexOf(stackTrace, LINE_PATTERNS);
288 assertThat(result[0], is(40));
289 assertThat(result[1], is(0));
290 String errorLine = TestSuiteXmlParser.parseErrorLine(stackTrace, "org.apache.Test");
291 assertThat(errorLine, is("30"));
292 }
293
294 @Test
295 public void lastIndexOfPatternOfOrdinalTestWithCause() {
296 final StringBuilder stackTrace = new StringBuilder(
297 "\tat org.apache.Test.util(Test.java:60)\n" + "\tat org.apache.Test.test(Test.java:30)\n"
298 + "\tat com.sun.Impl.xyz(Impl.java:258)\n"
299 + "\tat Caused by: java.lang.IndexOutOfBoundsException\n"
300 + "\tat org.apache.Test.util(Test.java:70)\n");
301
302 int[] result = TestSuiteXmlParser.lastIndexOf(stackTrace, LINE_PATTERNS);
303 assertThat(result[0], is(40));
304 assertThat(result[1], is(0));
305 String errorLine = TestSuiteXmlParser.parseErrorLine(stackTrace, "org.apache.Test");
306 assertThat(errorLine, is("30"));
307 }
308
309 @Test
310 public void lastIndexOfPatternOfEnclosedTest() {
311 final StringBuilder source = new StringBuilder("\tat org.apache.Test.util(Test.java:60)\n"
312 + "\tat org.apache.Test$Nested.test(Test.java:30)\n"
313 + "\tat com.sun.Impl.xyz(Impl.java:258)\n");
314
315 int[] result = TestSuiteXmlParser.lastIndexOf(source, LINE_PATTERNS);
316 assertThat(result[0], is(40));
317 assertThat(result[1], is(1));
318 String errorLine = TestSuiteXmlParser.parseErrorLine(source, "org.apache.Test$Nested");
319 assertThat(errorLine, is("30"));
320 }
321
322 @Test
323 public void lastIndexOfPatternOfEnclosedTestWithCause() {
324 final StringBuilder source = new StringBuilder(
325 "\tat org.apache.Test.util(Test.java:60)\n" + "\tat org.apache.Test$Nested.test(Test.java:30)\n"
326 + "\tat com.sun.Impl.xyz(Impl.java:258)\n"
327 + "\tat Caused by: java.lang.IndexOutOfBoundsException\n"
328 + "\tat org.apache.Test$Nested.util(Test.java:70)\n");
329
330 int[] result = TestSuiteXmlParser.lastIndexOf(source, LINE_PATTERNS);
331 assertThat(result[0], is(40));
332 assertThat(result[1], is(1));
333 String errorLine = TestSuiteXmlParser.parseErrorLine(source, "org.apache.Test$Nested");
334 assertThat(errorLine, is("30"));
335 }
336
337 @Test
338 public void shouldParserEverythingInOrdinalTest() throws Exception {
339 TestSuiteXmlParser parser = new TestSuiteXmlParser(consoleLogger);
340 List<ReportTestSuite> tests =
341 parser.parse("src/test/resources/fixture/testsuitexmlparser/TEST-surefire.MyTest.xml");
342 assertTrue(parser.isValid());
343 assertThat(tests.size(), is(1));
344 assertThat(tests.get(0).getFullClassName(), is("surefire.MyTest"));
345 assertThat(tests.get(0).getNumberOfErrors(), is(1));
346 assertThat(tests.get(0).getNumberOfFlakes(), is(0));
347 assertThat(tests.get(0).getNumberOfSkipped(), is(0));
348 assertThat(tests.get(0).getNumberOfFailures(), is(0));
349 assertThat(tests.get(0).getPackageName(), is("surefire"));
350 assertThat(tests.get(0).getNumberOfTests(), is(1));
351 assertThat(tests.get(0).getTestCases().size(), is(1));
352 assertFalse(tests.get(0).getTestCases().get(0).isSuccessful());
353 assertThat(tests.get(0).getTestCases().get(0).getFailureErrorLine(), is("13"));
354 assertThat(tests.get(0).getTestCases().get(0).getFailureType(), is("java.lang.RuntimeException"));
355 assertThat(tests.get(0).getTestCases().get(0).getFullClassName(), is("surefire.MyTest"));
356 assertThat(tests.get(0).getTestCases().get(0).getClassName(), is("MyTest"));
357 assertThat(tests.get(0).getTestCases().get(0).getName(), is("test"));
358 assertThat(tests.get(0).getTestCases().get(0).getFullName(), is("surefire.MyTest.test"));
359 assertThat(tests.get(0).getTestCases().get(0).getTime(), is(0.1f));
360 assertThat(tests.get(0).getTestCases().get(0).getFailureMessage(), is("this is different message"));
361
362 assertThat(
363 tests.get(0).getTestCases().get(0).getFailureDetail(),
364 is("java.lang.RuntimeException: java.lang.IndexOutOfBoundsException\n"
365 + "\tat surefire.MyTest.rethrownDelegate(MyTest.java:24)\n"
366 + "\tat surefire.MyTest.newRethrownDelegate(MyTest.java:17)\n"
367 + "\tat surefire.MyTest.test(MyTest.java:13)\n"
368 + "\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n"
369 + "\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)\n"
370 + "\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n"
371 + "\tat java.lang.reflect.Method.invoke(Method.java:606)\n"
372 + "\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)\n"
373 + "\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)\n"
374 + "\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)\n"
375 + "\tat org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)\n"
376 + "\tat org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)\n"
377 + "\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)\n"
378 + "\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)\n"
379 + "\tat org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)\n"
380 + "\tat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)\n"
381 + "\tat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)\n"
382 + "\tat org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)\n"
383 + "\tat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)\n"
384 + "\tat org.junit.runners.ParentRunner.run(ParentRunner.java:363)\n"
385 + "\tat org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:272)\n"
386 + "\tat org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:167)\n"
387 + "\tat org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:147)\n"
388 + "\tat org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:130)\n"
389 + "\tat org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:211)\n"
390 + "\tat org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:163)\n"
391 + "\tat org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:105)\n"
392 + "\tCaused by: java.lang.IndexOutOfBoundsException\n"
393 + "\tat surefire.MyTest.failure(MyTest.java:33)\n"
394 + "\tat surefire.MyTest.access$100(MyTest.java:9)\n"
395 + "\tat surefire.MyTest$Nested.run(MyTest.java:38)\n"
396 + "\tat surefire.MyTest.delegate(MyTest.java:29)\n"
397 + "\tat surefire.MyTest.rethrownDelegate(MyTest.java:22)"));
398 assertThat(tests.get(0).getTestCases().get(0).hasError(), is(true));
399 }
400
401 @Test
402 public void shouldParserEverythingInEnclosedTest() throws Exception {
403 TestSuiteXmlParser parser = new TestSuiteXmlParser(consoleLogger);
404 List<ReportTestSuite> tests =
405 parser.parse("src/test/resources/fixture/testsuitexmlparser/TEST-surefire.MyTest-enclosed.xml");
406 assertTrue(parser.isValid());
407 assertThat(tests.size(), is(1));
408 assertThat(tests.get(0).getFullClassName(), is("surefire.MyTest$A"));
409 assertThat(tests.get(0).getNumberOfErrors(), is(1));
410 assertThat(tests.get(0).getNumberOfFlakes(), is(0));
411 assertThat(tests.get(0).getNumberOfSkipped(), is(0));
412 assertThat(tests.get(0).getNumberOfFailures(), is(0));
413 assertThat(tests.get(0).getPackageName(), is("surefire"));
414 assertThat(tests.get(0).getNumberOfTests(), is(1));
415 assertThat(tests.get(0).getTestCases().size(), is(1));
416 assertFalse(tests.get(0).getTestCases().get(0).isSuccessful());
417 assertThat(tests.get(0).getTestCases().get(0).getFailureErrorLine(), is("45"));
418 assertThat(tests.get(0).getTestCases().get(0).getFailureType(), is("java.lang.RuntimeException"));
419 assertThat(tests.get(0).getTestCases().get(0).getFullClassName(), is("surefire.MyTest$A"));
420 assertThat(tests.get(0).getTestCases().get(0).getClassName(), is("MyTest$A"));
421 assertThat(tests.get(0).getTestCases().get(0).getName(), is("t"));
422 assertThat(tests.get(0).getTestCases().get(0).getFullName(), is("surefire.MyTest$A.t"));
423 assertThat(tests.get(0).getTestCases().get(0).getTime(), is(0f));
424
425 assertThat(tests.get(0).getTestCases().get(0).getFailureMessage(), is("java.lang.IndexOutOfBoundsException"));
426
427 assertThat(
428 tests.get(0).getTestCases().get(0).getFailureDetail(),
429 is("java.lang.RuntimeException: java.lang.IndexOutOfBoundsException\n"
430 + "\tat surefire.MyTest.rethrownDelegate(MyTest.java:24)\n"
431 + "\tat surefire.MyTest.newRethrownDelegate(MyTest.java:17)\n"
432 + "\tat surefire.MyTest.access$200(MyTest.java:9)\n"
433 + "\tat surefire.MyTest$A.t(MyTest.java:45)\n"
434 + "\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n"
435 + "\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)\n"
436 + "\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n"
437 + "\tat java.lang.reflect.Method.invoke(Method.java:606)\n"
438 + "\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)\n"
439 + "\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)\n"
440 + "\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)\n"
441 + "\tat org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)\n"
442 + "\tat org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)\n"
443 + "\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)\n"
444 + "\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)\n"
445 + "\tat org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)\n"
446 + "\tat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)\n"
447 + "\tat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)\n"
448 + "\tat org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)\n"
449 + "\tat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)\n"
450 + "\tat org.junit.runners.ParentRunner.run(ParentRunner.java:363)\n"
451 + "\tat org.junit.runners.Suite.runChild(Suite.java:128)\n"
452 + "\tat org.junit.runners.Suite.runChild(Suite.java:27)\n"
453 + "\tat org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)\n"
454 + "\tat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)\n"
455 + "\tat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)\n"
456 + "\tat org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)\n"
457 + "\tat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)\n"
458 + "\tat org.junit.runners.ParentRunner.run(ParentRunner.java:363)\n"
459 + "\tat org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:272)\n"
460 + "\tat org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:167)\n"
461 + "\tat org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:147)\n"
462 + "\tat org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:130)\n"
463 + "\tat org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:211)\n"
464 + "\tat org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:163)\n"
465 + "\tat org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:105)\n"
466 + "\tCaused by: java.lang.IndexOutOfBoundsException\n"
467 + "\tat surefire.MyTest.failure(MyTest.java:33)\n"
468 + "\tat surefire.MyTest.access$100(MyTest.java:9)\n"
469 + "\tat surefire.MyTest$Nested.run(MyTest.java:38)\n"
470 + "\tat surefire.MyTest.delegate(MyTest.java:29)\n"
471 + "\tat surefire.MyTest.rethrownDelegate(MyTest.java:22)\n"));
472 assertThat(tests.get(0).getTestCases().get(0).hasError(), is(true));
473 }
474
475 @Test
476 public void shouldParserEverythingInEnclosedTrimStackTraceTest() throws Exception {
477 TestSuiteXmlParser parser = new TestSuiteXmlParser(consoleLogger);
478 List<ReportTestSuite> tests = parser.parse(
479 "src/test/resources/fixture/testsuitexmlparser/TEST-surefire.MyTest-enclosed-trimStackTrace.xml");
480 assertTrue(parser.isValid());
481 assertThat(tests.size(), is(1));
482 assertThat(tests.get(0).getFullClassName(), is("surefire.MyTest$A"));
483 assertThat(tests.get(0).getNumberOfErrors(), is(1));
484 assertThat(tests.get(0).getNumberOfFlakes(), is(0));
485 assertThat(tests.get(0).getNumberOfSkipped(), is(0));
486 assertThat(tests.get(0).getNumberOfFailures(), is(0));
487 assertThat(tests.get(0).getPackageName(), is("surefire"));
488 assertThat(tests.get(0).getNumberOfTests(), is(1));
489 assertThat(tests.get(0).getTestCases().size(), is(1));
490 assertFalse(tests.get(0).getTestCases().get(0).isSuccessful());
491 assertThat(tests.get(0).getTestCases().get(0).getFailureErrorLine(), is("45"));
492 assertThat(tests.get(0).getTestCases().get(0).getFailureType(), is("java.lang.RuntimeException"));
493 assertThat(tests.get(0).getTestCases().get(0).getFullClassName(), is("surefire.MyTest$A"));
494 assertThat(tests.get(0).getTestCases().get(0).getClassName(), is("MyTest$A"));
495 assertThat(tests.get(0).getTestCases().get(0).getName(), is("t"));
496 assertThat(tests.get(0).getTestCases().get(0).getFullName(), is("surefire.MyTest$A.t"));
497 assertThat(tests.get(0).getTestCases().get(0).getTime(), is(0f));
498
499 assertThat(tests.get(0).getTestCases().get(0).getFailureMessage(), is("java.lang.IndexOutOfBoundsException"));
500
501 assertThat(
502 tests.get(0).getTestCases().get(0).getFailureDetail(),
503 is("java.lang.RuntimeException: java.lang.IndexOutOfBoundsException\n"
504 + "\tat surefire.MyTest.failure(MyTest.java:33)\n"
505 + "\tat surefire.MyTest.access$100(MyTest.java:9)\n"
506 + "\tat surefire.MyTest$Nested.run(MyTest.java:38)\n"
507 + "\tat surefire.MyTest.delegate(MyTest.java:29)\n"
508 + "\tat surefire.MyTest.rethrownDelegate(MyTest.java:22)\n"
509 + "\tat surefire.MyTest.newRethrownDelegate(MyTest.java:17)\n"
510 + "\tat surefire.MyTest.access$200(MyTest.java:9)\n"
511 + "\tat surefire.MyTest$A.t(MyTest.java:45)\n"));
512 assertThat(tests.get(0).getTestCases().get(0).hasError(), is(true));
513 }
514
515 @Test
516 public void shouldParserEverythingInNestedClassTest() throws Exception {
517 TestSuiteXmlParser parser = new TestSuiteXmlParser(consoleLogger);
518 List<ReportTestSuite> tests =
519 parser.parse("src/test/resources/fixture/testsuitexmlparser/TEST-surefire.MyTest-nestedClass.xml");
520 assertTrue(parser.isValid());
521 assertThat(tests.size(), is(1));
522 assertThat(tests.get(0).getFullClassName(), is("surefire.MyTest"));
523 assertThat(tests.get(0).getNumberOfErrors(), is(1));
524 assertThat(tests.get(0).getNumberOfFlakes(), is(0));
525 assertThat(tests.get(0).getNumberOfSkipped(), is(0));
526 assertThat(tests.get(0).getNumberOfFailures(), is(0));
527 assertThat(tests.get(0).getPackageName(), is("surefire"));
528 assertThat(tests.get(0).getNumberOfTests(), is(1));
529 assertThat(tests.get(0).getTestCases().size(), is(1));
530 assertFalse(tests.get(0).getTestCases().get(0).isSuccessful());
531 assertThat(tests.get(0).getTestCases().get(0).getFailureErrorLine(), is("13"));
532 assertThat(tests.get(0).getTestCases().get(0).getFailureType(), is("java.lang.RuntimeException"));
533 assertThat(tests.get(0).getTestCases().get(0).getFullClassName(), is("surefire.MyTest"));
534 assertThat(tests.get(0).getTestCases().get(0).getClassName(), is("MyTest"));
535 assertThat(tests.get(0).getTestCases().get(0).getName(), is("test"));
536 assertThat(tests.get(0).getTestCases().get(0).getFullName(), is("surefire.MyTest.test"));
537 assertThat(tests.get(0).getTestCases().get(0).getTime(), is(0f));
538
539 assertThat(tests.get(0).getTestCases().get(0).getFailureMessage(), is("java.lang.IndexOutOfBoundsException"));
540
541 assertThat(
542 tests.get(0).getTestCases().get(0).getFailureDetail(),
543 is("java.lang.RuntimeException: java.lang.IndexOutOfBoundsException\n"
544 + "\tat surefire.MyTest.rethrownDelegate(MyTest.java:24)\n"
545 + "\tat surefire.MyTest.newRethrownDelegate(MyTest.java:17)\n"
546 + "\tat surefire.MyTest.test(MyTest.java:13)\n"
547 + "\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n"
548 + "\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)\n"
549 + "\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n"
550 + "\tat java.lang.reflect.Method.invoke(Method.java:606)\n"
551 + "\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)\n"
552 + "\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)\n"
553 + "\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)\n"
554 + "\tat org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)\n"
555 + "\tat org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)\n"
556 + "\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)\n"
557 + "\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)\n"
558 + "\tat org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)\n"
559 + "\tat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)\n"
560 + "\tat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)\n"
561 + "\tat org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)\n"
562 + "\tat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)\n"
563 + "\tat org.junit.runners.ParentRunner.run(ParentRunner.java:363)\n"
564 + "\tat org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:272)\n"
565 + "\tat org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:167)\n"
566 + "\tat org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:147)\n"
567 + "\tat org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:130)\n"
568 + "\tat org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:211)\n"
569 + "\tat org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:163)\n"
570 + "\tat org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:105)\n"
571 + "\tCaused by: java.lang.IndexOutOfBoundsException\n"
572 + "\tat surefire.MyTest.failure(MyTest.java:33)\n"
573 + "\tat surefire.MyTest.access$100(MyTest.java:9)\n"
574 + "\tat surefire.MyTest$Nested.run(MyTest.java:38)\n"
575 + "\tat surefire.MyTest.delegate(MyTest.java:29)\n"
576 + "\tat surefire.MyTest.rethrownDelegate(MyTest.java:22)"));
577 assertThat(tests.get(0).getTestCases().get(0).hasError(), is(true));
578 }
579
580 @Test
581 public void shouldParserEverythingInNestedClassTrimStackTraceTest() throws Exception {
582 TestSuiteXmlParser parser = new TestSuiteXmlParser(consoleLogger);
583 List<ReportTestSuite> tests = parser.parse(
584 "src/test/resources/fixture/testsuitexmlparser/TEST-surefire.MyTest-nestedClass-trimStackTrace.xml");
585 assertTrue(parser.isValid());
586 assertThat(tests.size(), is(1));
587 assertThat(tests.get(0).getFullClassName(), is("surefire.MyTest"));
588 assertThat(tests.get(0).getNumberOfErrors(), is(1));
589 assertThat(tests.get(0).getNumberOfFlakes(), is(0));
590 assertThat(tests.get(0).getNumberOfSkipped(), is(0));
591 assertThat(tests.get(0).getNumberOfFailures(), is(0));
592 assertThat(tests.get(0).getPackageName(), is("surefire"));
593 assertThat(tests.get(0).getNumberOfTests(), is(1));
594 assertThat(tests.get(0).getTestCases().size(), is(1));
595 assertFalse(tests.get(0).getTestCases().get(0).isSuccessful());
596 assertThat(tests.get(0).getTestCases().get(0).getFailureErrorLine(), is("13"));
597 assertThat(tests.get(0).getTestCases().get(0).getFailureType(), is("java.lang.RuntimeException"));
598 assertThat(tests.get(0).getTestCases().get(0).getFullClassName(), is("surefire.MyTest"));
599 assertThat(tests.get(0).getTestCases().get(0).getClassName(), is("MyTest"));
600 assertThat(tests.get(0).getTestCases().get(0).getName(), is("test"));
601 assertThat(tests.get(0).getTestCases().get(0).getFullName(), is("surefire.MyTest.test"));
602 assertThat(tests.get(0).getTestCases().get(0).getTime(), is(0f));
603
604 assertThat(tests.get(0).getTestCases().get(0).getFailureMessage(), is("java.lang.IndexOutOfBoundsException"));
605
606 assertThat(
607 tests.get(0).getTestCases().get(0).getFailureDetail(),
608 is("java.lang.RuntimeException: java.lang.IndexOutOfBoundsException\n"
609 + "\tat surefire.MyTest.rethrownDelegate(MyTest.java:24)\n"
610 + "\tat surefire.MyTest.newRethrownDelegate(MyTest.java:17)\n"
611 + "\tat surefire.MyTest.test(MyTest.java:13)\n"
612 + "\tCaused by: java.lang.IndexOutOfBoundsException\n"
613 + "\tat surefire.MyTest.failure(MyTest.java:33)\n"
614 + "\tat surefire.MyTest.access$100(MyTest.java:9)\n"
615 + "\tat surefire.MyTest$Nested.run(MyTest.java:38)\n"
616 + "\tat surefire.MyTest.delegate(MyTest.java:29)\n"
617 + "\tat surefire.MyTest.rethrownDelegate(MyTest.java:22)"));
618 assertThat(tests.get(0).getTestCases().get(0).hasError(), is(true));
619 }
620
621 @Test
622 public void shouldTestNotBlank() {
623 assertFalse(TestSuiteXmlParser.isNotBlank(1, 2, ' ', ' ', ' ', '\n'));
624 assertFalse(TestSuiteXmlParser.isNotBlank(1, 2, ' ', '\t', ' ', '\n'));
625 assertFalse(TestSuiteXmlParser.isNotBlank(1, 2, ' ', ' ', '\r', '\n'));
626 assertFalse(TestSuiteXmlParser.isNotBlank(1, 2, ' ', ' ', '\f', '\n'));
627 assertTrue(TestSuiteXmlParser.isNotBlank(1, 2, ' ', 'a', ' ', '\n'));
628 assertTrue(TestSuiteXmlParser.isNotBlank(1, 2, ' ', ' ', 'a', '\n'));
629 assertTrue(TestSuiteXmlParser.isNotBlank(1, 2, ' ', 'a', 'b', '\n'));
630 }
631
632 @Test
633 public void shouldTestIsNumeric() {
634 assertFalse(TestSuiteXmlParser.isNumeric(new StringBuilder("0?5142"), 1, 3));
635 assertTrue(TestSuiteXmlParser.isNumeric(new StringBuilder("0?51M2"), 2, 4));
636 assertFalse(TestSuiteXmlParser.isNumeric(new StringBuilder("0?51M2"), 2, 5));
637 }
638
639 @Test
640 public void shouldParseLargeFile() throws Exception {
641
642 Path tempFile = Files.createTempFile("largeReport", ".xml");
643
644 try (BufferedWriter w = Files.newBufferedWriter(tempFile)) {
645 w.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
646 + "<testsuite failures=\"1\" time=\"2.413\" errors=\"0\" skipped=\"0\" tests=\"2\" name=\"largeFile.TestSurefire3\">\n"
647 + " <properties></properties>\n"
648 + " <testcase time=\"0.005\" classname=\"largeFile.TestSurefire3\" name=\"testSuccess\" />\n"
649 + " <testcase time=\"2.20\" classname=\"largeFile.TestSurefire3\" name=\"testFailure\">\n"
650 + " <failure message=\"test failure\" type=\"junit.framework.AssertionFailedError\">junit.framework.AssertionFailedError: \n"
651 + "\tat junit.framework.Assert.fail(Assert.java:47)\n"
652 + "\tat largeFile.TestSurefire3.testFailure(TestSurefire3.java:40)\n"
653 + "</failure>\n"
654 + " <system-err><![CDATA[\n");
655
656
657 for (int i = 0; i < 100000; i++) {
658 w.write(
659 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n");
660 w.flush();
661 }
662 w.write("]]></system-err>\n" + " </testcase>\n" + "</testsuite>\n");
663 w.flush();
664 }
665
666 System.err.println(Files.size(tempFile));
667
668
669 TestSuiteXmlParser testSuiteXmlParser = new TestSuiteXmlParser(consoleLogger);
670
671 try (InputStreamReader is = new InputStreamReader(Files.newInputStream(tempFile), UTF_8)) {
672 List<ReportTestSuite> parse = testSuiteXmlParser.parse(is);
673
674 assertThat(parse.size(), is(1));
675 ReportTestSuite report = parse.get(0);
676 assertThat(report.getFullClassName(), is("largeFile.TestSurefire3"));
677 assertThat(report.getName(), is("TestSurefire3"));
678 assertThat(report.getPackageName(), is("largeFile"));
679 assertThat(report.getNumberOfTests(), is(2));
680 assertThat(report.getNumberOfSkipped(), is(0));
681 assertThat(report.getNumberOfErrors(), is(0));
682 assertThat(report.getNumberOfFailures(), is(1));
683 assertThat(report.getNumberOfFlakes(), is(0));
684 assertThat(report.getTimeElapsed(), is(2.413f));
685 assertThat(report.getTestCases().size(), is(2));
686
687 List<ReportTestCase> tests = report.getTestCases();
688 assertThat(tests.get(0).getFullClassName(), is("largeFile.TestSurefire3"));
689 assertThat(tests.get(0).getName(), is("testSuccess"));
690 assertNull(tests.get(0).getFailureDetail());
691 assertThat(tests.get(0).getClassName(), is("TestSurefire3"));
692 assertThat(tests.get(0).getTime(), is(0.005f));
693 assertThat(tests.get(0).getFullName(), is("largeFile.TestSurefire3.testSuccess"));
694 assertThat(tests.get(0).hasError(), is(false));
695
696 assertThat(tests.get(1).getFullClassName(), is("largeFile.TestSurefire3"));
697 assertThat(tests.get(1).getName(), is("testFailure"));
698 assertThat(
699 tests.get(1).getFailureDetail(),
700 is("junit.framework.AssertionFailedError: \n"
701 + "\tat junit.framework.Assert.fail(Assert.java:47)\n"
702 + "\tat largeFile.TestSurefire3.testFailure(TestSurefire3.java:40)\n"));
703 assertThat(tests.get(1).getClassName(), is("TestSurefire3"));
704 assertThat(tests.get(1).getTime(), is(2.20f));
705 assertThat(tests.get(1).getFailureErrorLine(), is("40"));
706 assertThat(tests.get(1).getFailureMessage(), is("test failure"));
707 assertThat(tests.get(1).getFullName(), is("largeFile.TestSurefire3.testFailure"));
708 assertThat(tests.get(1).getFailureType(), is("junit.framework.AssertionFailedError"));
709 assertThat(tests.get(1).hasError(), is(false));
710 }
711
712
713 Files.delete(tempFile);
714 }
715
716 @Test
717 public void shouldParseFlakes() throws Exception {
718
719 TestSuiteXmlParser parser = new TestSuiteXmlParser(consoleLogger);
720
721 List<ReportTestSuite> testSuites =
722 parser.parse("src/test/resources/fixture/testsuitexmlparser/TEST-org.acme.FlakyTest.xml");
723 assertTrue(parser.isValid());
724 assertThat(testSuites.size(), is(1));
725
726 assertThat(testSuites.size(), is(1));
727 ReportTestSuite report = testSuites.get(0);
728 assertThat(report.getFullClassName(), is("org.acme.FlakyTest"));
729 assertThat(report.getName(), is("FlakyTest"));
730 assertThat(report.getPackageName(), is("org.acme"));
731 assertThat(report.getNumberOfTests(), is(2));
732 assertThat(report.getNumberOfSkipped(), is(0));
733 assertThat(report.getNumberOfErrors(), is(0));
734 assertThat(report.getNumberOfFailures(), is(0));
735 assertThat(report.getNumberOfFlakes(), is(4));
736 assertThat(report.getTimeElapsed(), is(1.324f));
737 assertThat(report.getTestCases().size(), is(2));
738
739 List<ReportTestCase> tests = report.getTestCases();
740 assertThat(tests.get(0).getFullClassName(), is("org.acme.FlakyTest"));
741 assertThat(tests.get(0).getName(), is("testFlaky"));
742 assertNull(tests.get(0).getFailureDetail());
743 assertThat(tests.get(0).getClassName(), is("FlakyTest"));
744 assertThat(tests.get(0).getTime(), is(0.034f));
745 assertThat(tests.get(0).getFullName(), is("org.acme.FlakyTest.testFlaky"));
746 assertThat(tests.get(0).hasError(), is(false));
747 assertThat(tests.get(0).hasFlakes(), is(true));
748
749 List<FlakyFailure> flakyFailures = tests.get(0).getFlakyFailures();
750 assertThat(flakyFailures.size(), is(3));
751
752 assertThat(flakyFailures.get(0).getMessage(), startsWith("expected: <1> but was: <0>"));
753 assertThat(flakyFailures.get(0).getType(), is("org.opentest4j.AssertionFailedError"));
754 assertThat(
755 flakyFailures.get(0).getStackTrace(),
756 containsString("at org.acme.FlakyTest.testFlaky(FlakyTest.java:18)"));
757
758 assertThat(flakyFailures.get(1).getMessage(), startsWith("expected: <1> but was: <3>"));
759 assertThat(flakyFailures.get(1).getType(), is("org.opentest4j.AssertionFailedError"));
760 assertThat(
761 flakyFailures.get(1).getStackTrace(),
762 containsString("at org.acme.FlakyTest.testFlaky(FlakyTest.java:18)"));
763
764 assertThat(flakyFailures.get(2).getMessage(), startsWith("expected: <1> but was: <4>"));
765 assertThat(flakyFailures.get(2).getType(), is("org.opentest4j.AssertionFailedError"));
766 assertThat(
767 flakyFailures.get(2).getStackTrace(),
768 containsString("at org.acme.FlakyTest.testFlaky(FlakyTest.java:18)"));
769
770 List<FlakyError> flakyErrors = tests.get(0).getFlakyErrors();
771 assertThat(flakyErrors.size(), is(1));
772 assertThat(flakyErrors.get(0).getMessage(), startsWith("expected: <1> but was: <0>"));
773 assertThat(flakyErrors.get(0).getType(), is("org.opentest4j.AssertionFailedError"));
774 assertThat(
775 flakyErrors.get(0).getStackTrace(),
776 containsString("at org.acme.FlakyTest.testFlaky(FlakyTest.java:18)"));
777
778 assertThat(tests.get(1).getFullClassName(), is("org.acme.FlakyTest"));
779 assertThat(tests.get(1).getName(), is("testStable"));
780 assertThat(tests.get(1).getClassName(), is("FlakyTest"));
781 assertThat(tests.get(1).getTime(), is(0.001f));
782 assertThat(tests.get(1).getFullName(), is("org.acme.FlakyTest.testStable"));
783 assertThat(tests.get(1).hasError(), is(false));
784 assertThat(tests.get(1).hasFlakes(), is(false));
785 }
786 }