diff --git a/test_runner/src/main/kotlin/ftl/util/OutcomeDetailsFormatter.kt b/test_runner/src/main/kotlin/ftl/util/OutcomeDetailsFormatter.kt index d5c47d855a..55b93766d6 100644 --- a/test_runner/src/main/kotlin/ftl/util/OutcomeDetailsFormatter.kt +++ b/test_runner/src/main/kotlin/ftl/util/OutcomeDetailsFormatter.kt @@ -4,7 +4,6 @@ import com.google.api.services.toolresults.model.FailureDetail import com.google.api.services.toolresults.model.InconclusiveDetail import com.google.api.services.toolresults.model.Outcome import com.google.api.services.toolresults.model.SkippedDetail -import com.google.api.services.toolresults.model.SuccessDetail import ftl.reports.api.data.TestSuiteOverviewData import ftl.util.StepOutcome.failure import ftl.util.StepOutcome.flaky @@ -12,10 +11,14 @@ import ftl.util.StepOutcome.inconclusive import ftl.util.StepOutcome.skipped import ftl.util.StepOutcome.success import ftl.util.StepOutcome.unset -import java.lang.StringBuilder fun Outcome.getDetails(testSuiteOverviewData: TestSuiteOverviewData?) = when (summary) { - success, flaky -> testSuiteOverviewData?.let { getSuccessOutcomeDetails(it, successDetail) } + success, flaky -> testSuiteOverviewData?.let { + getSuccessOutcomeDetails( + testSuiteOverviewData = it, + otherNativeCrash = successDetail?.otherNativeCrash ?: false + ) + } failure -> failureDetail.getFailureOutcomeDetails(testSuiteOverviewData) inconclusive -> inconclusiveDetail.formatOutcomeDetails() skipped -> skippedDetail.formatOutcomeDetails() @@ -25,32 +28,31 @@ fun Outcome.getDetails(testSuiteOverviewData: TestSuiteOverviewData?) = when (su private fun getSuccessOutcomeDetails( testSuiteOverviewData: TestSuiteOverviewData, - successDetail: SuccessDetail? + otherNativeCrash: Boolean ) = StringBuilder("${testSuiteOverviewData.successCount} test cases passed").apply { if (testSuiteOverviewData.skipped > 0) append(skippedMessage(testSuiteOverviewData.skipped)) if (testSuiteOverviewData.flakes > 0) append(flakesMessage(testSuiteOverviewData.flakes)) - if (successDetail?.otherNativeCrash == true) append(NATIVE_CRASH_MESSAGE) + if (otherNativeCrash) append(NATIVE_CRASH_MESSAGE) }.toString() private val TestSuiteOverviewData.successCount get() = total - errors - failures - skipped - flakes private fun FailureDetail?.getFailureOutcomeDetails(testSuiteOverviewData: TestSuiteOverviewData?) = when { - this == null -> testSuiteOverviewData?.buildFailureOutcomeDetailsSummary() + this == null -> testSuiteOverviewData?.buildFailureOutcomeDetailsSummary() ?: "Unknown failure" crashed == true -> "Application crashed" timedOut == true -> "Test timed out" notInstalled == true -> "App failed to install" - else -> testSuiteOverviewData?.buildFailureOutcomeDetailsSummary() + else -> testSuiteOverviewData?.buildFailureOutcomeDetailsSummary() ?: "Unknown failure" } + this?.takeIf { it.otherNativeCrash }?.let { NATIVE_CRASH_MESSAGE }.orEmpty() -private fun TestSuiteOverviewData.buildFailureOutcomeDetailsSummary(): String { - return StringBuilder("$failures test casess failed").apply { +private fun TestSuiteOverviewData.buildFailureOutcomeDetailsSummary() = + StringBuilder("$failures test cases failed").apply { if (errors > 0) append(errorMessage(errors)) successCount.takeIf { it > 0 }?.let { append(successMessage(it)) } if (skipped > 0) append(skippedMessage(skipped)) if (flakes > 0) append(flakesMessage(flakes)) }.toString() -} private fun InconclusiveDetail?.formatOutcomeDetails() = when { this == null -> "Unknown reason" diff --git a/test_runner/src/test/kotlin/ftl/util/OutcomeDetailsFormatterTest.kt b/test_runner/src/test/kotlin/ftl/util/OutcomeDetailsFormatterTest.kt index 540a8b0d97..03fcba060b 100644 --- a/test_runner/src/test/kotlin/ftl/util/OutcomeDetailsFormatterTest.kt +++ b/test_runner/src/test/kotlin/ftl/util/OutcomeDetailsFormatterTest.kt @@ -63,7 +63,7 @@ internal class OutcomeDetailsFormatterTest { } } val testSuiteOverviewData = TestSuiteOverviewData(12, 3, 3, 3, 2, 0.0, 0.0) - val expectedMessage = "${testSuiteOverviewData.failures} test casess failed, " + + val expectedMessage = "${testSuiteOverviewData.failures} test cases failed, " + "${testSuiteOverviewData.errors} errors, " + "1 passed, " + "${testSuiteOverviewData.skipped} skipped, " + @@ -139,6 +139,43 @@ internal class OutcomeDetailsFormatterTest { assertEquals(expectedMessage, result) } + @Test + fun `Should return unknown failure message for failed-null testSuiteOverviewData`() { + // given + val mockedOutcome = mockk { + every { summary } returns StepOutcome.failure + every { failureDetail } returns mockk { + every { crashed } returns false + every { timedOut } returns false + every { notInstalled } returns false + every { otherNativeCrash } returns false + } + } + val expectedMessage = "Unknown failure" + + // when + val result = mockedOutcome.getDetails(null) + + // then + assertEquals(expectedMessage, result) + } + + @Test + fun `Should return unknown failure message for failed-null testSuiteOverviewData and failure details present`() { + // given + val mockedOutcome = mockk { + every { summary } returns StepOutcome.failure + every { failureDetail } returns null + } + val expectedMessage = "Unknown failure" + + // when + val result = mockedOutcome.getDetails(null) + + // then + assertEquals(expectedMessage, result) + } + @Test fun `should contains message about native crash when it happens`() { // given