@@ -20,10 +20,12 @@ import io.qameta.allure.model.{Stage, Status}
2020import io .qameta .allure .scalatest .testdata ._
2121import io .qameta .allure .test .IsolatedLifecycle
2222import io .qameta .allure .test .{AllureResults , AllureResultsWriterStub , RunUtils }
23- import io .qameta .allure .test .AllureTestCommonsUtils .expectedHistoryId
23+ import io .qameta .allure .test .AllureTestCommonsUtils .{ attach , expectedHistoryId }
2424import io .qameta .allure .util .ResultsUtils .createParameter
25- import io .qameta .allure .{Allure , AllureLifecycle }
25+ import io .qameta .allure .{Allure , AllureLifecycle , Description }
2626import org .junit .jupiter .api .Test
27+ import org .opentest4j .AssertionFailedError
28+ import org .scalatest .events .{Event , Ordinal , RunAborted , SuiteAborted }
2729import org .scalatest .matchers .should .Matchers ._
2830import org .scalatest .tools .Runner
2931
@@ -86,6 +88,7 @@ class AllureScalatestTest {
8688 .map(item => item.getStatus)
8789
8890 every(statuses) shouldBe Status .PASSED
91+ results.getGlobals shouldBe empty
8992 }
9093
9194 @ Test
@@ -98,6 +101,7 @@ class AllureScalatestTest {
98101 .map(item => item.getStatus)
99102
100103 every(statuses) shouldBe Status .FAILED
104+ results.getGlobals shouldBe empty
101105 }
102106
103107 @ Test
@@ -111,6 +115,7 @@ class AllureScalatestTest {
111115 .toList
112116
113117 every(statuses) should be(Status .BROKEN )
118+ results.getGlobals shouldBe empty
114119 }
115120
116121 @ Test
@@ -124,6 +129,7 @@ class AllureScalatestTest {
124129 .toList
125130
126131 every(statuses) should be(Status .SKIPPED )
132+ results.getGlobals shouldBe empty
127133 }
128134
129135 @ Test
@@ -233,6 +239,131 @@ class AllureScalatestTest {
233239 }
234240 }
235241
242+ @ Test
243+ @ Description (" A failed beforeAll is reported as a global error with its suite context and exception details." )
244+ def shouldReportBeforeAllFailureAsGlobalError (): Unit = {
245+ val started = System .currentTimeMillis()
246+ val results = run(classOf [BeforeAllFailureSpec ])
247+
248+ results.getGlobals should have length 1
249+ val errors = results.getGlobals.asScala.flatMap(_.getErrors.asScala)
250+ errors should have length 1
251+ val error = errors.head
252+ error.getMessage should include(" BeforeAllFailureSpec" )
253+ error.getMessage should include(" beforeAll failed" )
254+ error.getTrace should include(" java.lang.IllegalStateException: beforeAll failed" )
255+ error.getTrace should include(" BeforeAllFailureSpec.beforeAll" )
256+ error.getTimestamp should be >= started
257+ error.getTimestamp should be <= System .currentTimeMillis()
258+ }
259+
260+ @ Test
261+ @ Description (" A failed afterAll is reported as a global error with its suite context and exception details." )
262+ def shouldReportAfterAllFailureAsGlobalError (): Unit = {
263+ val results = run(classOf [AfterAllFailureSpec ])
264+
265+ results.getGlobals should have length 1
266+ val errors = results.getGlobals.asScala.flatMap(_.getErrors.asScala)
267+ errors should have length 1
268+ val error = errors.head
269+ error.getMessage should include(" AfterAllFailureSpec" )
270+ error.getMessage should include(" afterAll failed" )
271+ error.getTrace should include(" java.lang.IllegalStateException: afterAll failed" )
272+ error.getTrace should include(" AfterAllFailureSpec.afterAll" )
273+ }
274+
275+ @ Test
276+ @ Description (" Suite construction failures are reported as run-level global errors." )
277+ def shouldReportSuiteConstructionFailureAsGlobalError (): Unit = {
278+ val results = run(classOf [ConstructorFailureSpec ])
279+
280+ results.getGlobals should have length 1
281+ val errors = results.getGlobals.asScala.flatMap(_.getErrors.asScala)
282+ errors should have length 1
283+ val error = errors.head
284+ error.getMessage should include(" ScalaTest run" )
285+ error.getTrace should include(" ConstructorFailureSpec" )
286+ error.getTrace should include(" suite construction failed" )
287+ }
288+
289+ @ Test
290+ @ Description (" A suite abort with no throwable is reported with its message on the supplied lifecycle." )
291+ def shouldReportSuiteAbortWithoutThrowable (): Unit = {
292+ val results = report(
293+ SuiteAborted (
294+ ordinal = new Ordinal (0 ),
295+ message = " suite initialization was interrupted" ,
296+ suiteName = " fixture suite" ,
297+ suiteId = " fixture-suite" ,
298+ suiteClassName = None
299+ )
300+ )
301+
302+ results.getGlobals should have length 1
303+ val errors = results.getGlobals.asScala.flatMap(_.getErrors.asScala)
304+ errors should have length 1
305+ val error = errors.head
306+ error.getMessage should include(" fixture suite" )
307+ error.getMessage should include(" suite initialization was interrupted" )
308+ error.getTrace shouldBe null
309+ error.getTimestamp should be > 0L
310+ }
311+
312+ @ Test
313+ @ Description (" A run abort with no throwable is reported with its message on the supplied lifecycle." )
314+ def shouldReportRunAbortWithoutThrowable (): Unit = {
315+ val results = report(
316+ RunAborted (
317+ ordinal = new Ordinal (0 ),
318+ message = " test discovery was interrupted" ,
319+ throwable = None
320+ )
321+ )
322+
323+ results.getGlobals should have length 1
324+ val errors = results.getGlobals.asScala.flatMap(_.getErrors.asScala)
325+ errors should have length 1
326+ val error = errors.head
327+ error.getMessage should include(" ScalaTest run" )
328+ error.getMessage should include(" test discovery was interrupted" )
329+ error.getTrace shouldBe null
330+ error.getTimestamp should be > 0L
331+ }
332+
333+ @ Test
334+ @ Description (" A run abort is reported with its event context, exception details, and comparison values." )
335+ def shouldReportRunAbortComparisonDetails (): Unit = {
336+ val cause = new AssertionFailedError (" global comparison failed" , " expected value" , " actual value" )
337+ val results = report(
338+ RunAborted (
339+ ordinal = new Ordinal (0 ),
340+ message = " ScalaTest initialization failed" ,
341+ throwable = Some (cause)
342+ )
343+ )
344+
345+ results.getGlobals should have length 1
346+ val errors = results.getGlobals.asScala.flatMap(_.getErrors.asScala)
347+ errors should have length 1
348+ val error = errors.head
349+ error.getMessage should include(" ScalaTest initialization failed" )
350+ error.getMessage should include(" global comparison failed" )
351+ error.getTrace should include(" org.opentest4j.AssertionFailedError: global comparison failed" )
352+ error.getExpected shouldBe cause.getExpected.toString
353+ error.getActual shouldBe cause.getActual.toString
354+ }
355+
356+ private def report (event : Event ): AllureResults = {
357+ val results = new AllureResultsWriterStub ()
358+ val reporter = new AllureScalatest (new AllureLifecycle (results))
359+ try {
360+ reporter(event)
361+ } finally {
362+ attach(results)
363+ }
364+ results
365+ }
366+
236367 private def run (clazz : Class [_]): AllureResults = {
237368 RunUtils .runTests { _ =>
238369 val args = new ListBuffer [String ]
0 commit comments