diff --git a/README.md b/README.md index a645334..c7f190d 100644 --- a/README.md +++ b/README.md @@ -227,6 +227,7 @@ There is a full setting table. All settings adjust by system variable: | allure.slf4j.log | duplicate allure step and attachment messages to Slf4j Logger | true | | allure.lifecycle.class | Set `AllureLifecycle` full class name | `ru.iopump.kotest.allure.api.Slf4JAllureLifecycle`| | kotest.allure.data.driven | Create new Allure test case on each new iteration in Data Driven tests or Property Testing | true | +| kotest.allure.step.shouldThrow ⚡NEW⚡ | Doesn't break test if step throws exception in shouldThrow block | true | | kotest.allure.meta.cleanup ⚡NEW⚡ | Clean all allure metadata (issue, tms, allureId) from test case name. `"My test name [JIRA-1](TMS-2)#3 - { ... }` - will be cleaned up to `"My test name"` in report. | true | All variables are very flexible, for example: `allure.jira.pattern` == `allure_jira_pattern` == `ALLURE.JIRA.PATTERN` == `ALLURE_JIRA_PATTERN` as `ENV` or `SYS` variable diff --git a/src/main/kotlin/ru/iopump/kotest/allure/api/KotestAllureConstant.kt b/src/main/kotlin/ru/iopump/kotest/allure/api/KotestAllureConstant.kt index 2f2460c..29a5ca6 100644 --- a/src/main/kotlin/ru/iopump/kotest/allure/api/KotestAllureConstant.kt +++ b/src/main/kotlin/ru/iopump/kotest/allure/api/KotestAllureConstant.kt @@ -122,6 +122,13 @@ object KotestAllureConstant { */ const val DATA_DRIVEN_SUPPORT = "kotest.allure.data.driven" + /** + * Enable shouldThrow support: doesn't break test if step throws exception in shouldThrow block + * + * Default = true - enable. (disable it if face unexpected behavior) + */ + const val STEP_SHOULD_THROW_SUPPORT = "kotest.allure.step.shouldThrow" + /** * Clean all allure metadata (issue, tms, allureId) from test case name. * diff --git a/src/main/kotlin/ru/iopump/kotest/allure/helper/InternalExecutionModel.kt b/src/main/kotlin/ru/iopump/kotest/allure/helper/InternalExecutionModel.kt index a430f81..085683f 100644 --- a/src/main/kotlin/ru/iopump/kotest/allure/helper/InternalExecutionModel.kt +++ b/src/main/kotlin/ru/iopump/kotest/allure/helper/InternalExecutionModel.kt @@ -7,7 +7,6 @@ import io.kotest.core.source.SourceRef.ClassSource import io.kotest.core.source.SourceRef.FileSource import io.kotest.core.source.SourceRef.None import io.kotest.core.test.TestResult.Success -import io.kotest.core.test.TestStatus import io.qameta.allure.model.StepResult import ru.iopump.kotest.allure.KotestAllureListener.log import ru.iopump.kotest.allure.api.KotestAllureConstant.VAR.DATA_DRIVEN_SUPPORT @@ -177,5 +176,5 @@ object InternalExecutionModel { private val KotestTestCase.parentUuid: String? get() = testUuidMap[descriptor.parent] - private val KotestTestResult.needPassOnTop: Boolean get() = status in arrayOf(TestStatus.Error, TestStatus.Failure) + private val KotestTestResult.needPassOnTop: Boolean get() = isErrorOrFailure } \ No newline at end of file diff --git a/src/main/kotlin/ru/iopump/kotest/allure/helper/InternalUtil.kt b/src/main/kotlin/ru/iopump/kotest/allure/helper/InternalUtil.kt index c61d458..6baaf1d 100644 --- a/src/main/kotlin/ru/iopump/kotest/allure/helper/InternalUtil.kt +++ b/src/main/kotlin/ru/iopump/kotest/allure/helper/InternalUtil.kt @@ -12,6 +12,7 @@ import org.opentest4j.TestAbortedException import org.slf4j.LoggerFactory import ru.iopump.kotest.allure.api.KotestAllureConstant import ru.iopump.kotest.allure.api.KotestAllureConstant.VAR.SKIP_ON_FAIL +import ru.iopump.kotest.allure.api.KotestAllureConstant.VAR.STEP_SHOULD_THROW_SUPPORT import ru.iopump.kotest.allure.api.KotestAllureConstant.VAR.TEST_NAME_AUTO_CLEAN_UP import ru.iopump.kotest.allure.api.KotestAllureExecution.bestName import ru.iopump.kotest.allure.helper.meta.AllureMetadata @@ -27,6 +28,8 @@ internal object InternalUtil { private val isAllureMetaCleanUp = TEST_NAME_AUTO_CLEAN_UP.prop(true) + private val isStepShouldThrowSupportEnabled = STEP_SHOULD_THROW_SUPPORT.prop(true) + internal inline fun T.toOptional() = Optional.ofNullable(this) internal fun String.logger() = LoggerFactory.getLogger(this) @@ -106,8 +109,9 @@ internal object InternalUtil { internal fun AllureTestResult.updateStatus(statusAndDetails: Pair) { // Kotest 5.4.X listener doesn't take into account child steps results. // We should find previous fail / broken child steps in ALLURE storage and use it on top - val closestPreviousErrorOrBrokenStatusAndDetails: Pair = + val closestPreviousErrorOrBrokenStatusAndDetails: Pair = statusAndDetails.takeIf { isStepShouldThrowSupportEnabled }.let { steps.map { it.status to it.statusDetails }.lastOrNull { it.first.isBrokenOrFailed } ?: statusAndDetails + } val effectiveStatusAndDetails = if (statusAndDetails.first.isNotPassed) statusAndDetails else closestPreviousErrorOrBrokenStatusAndDetails diff --git a/src/test/kotlin/ru/iopump/kotest/allure/ExampleStringSpec.kt b/src/test/kotlin/ru/iopump/kotest/allure/ExampleStringSpec.kt index 1a33ae1..ccfee2b 100644 --- a/src/test/kotlin/ru/iopump/kotest/allure/ExampleStringSpec.kt +++ b/src/test/kotlin/ru/iopump/kotest/allure/ExampleStringSpec.kt @@ -1,5 +1,6 @@ package ru.iopump.kotest.allure +import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.StringSpec import io.kotest.data.forAll import io.kotest.data.row @@ -7,6 +8,7 @@ import io.qameta.allure.Epic import io.qameta.allure.Feature import io.qameta.allure.Link import io.qameta.allure.Links +import io.qameta.allure.Step import ru.iopump.kotest.allure.api.KotestAllureExecution.setUpFixture import ru.iopump.kotest.allure.api.KotestAllureExecution.tearDownFixture @@ -33,6 +35,15 @@ class ExampleStringSpec : StringSpec() { } } + "If step throws exception in shouldThrow block test must not break" { + shouldThrow { throwException() } + } + tearDownFixture("Tear Down testing fixture") } + + @Step("Throw exception") + fun throwException() { + throw Exception() + } } \ No newline at end of file