Skip to content

Commit

Permalink
implemented beforeInvocation and afterInvocation hooks (#3589)
Browse files Browse the repository at this point in the history
* implemented beforeInvocation hook

* beforeInvocation - added to api

* beforeInvocation - added docs

* afterInvocation - added

* Adjusting tests

---------

Co-authored-by: Aleksey Yakovlev <aleksey.yakovlev@agoda.com>
Co-authored-by: Emil Kantis <emil.kantis@protonmail.com>
  • Loading branch information
3 people committed Jul 25, 2023
1 parent cf5537b commit 7727acf
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public abstract class io/kotest/core/TestConfiguration {
public final fun afterAny (Lkotlin/jvm/functions/Function2;)V
public final fun afterContainer (Lkotlin/jvm/functions/Function2;)V
public final fun afterEach (Lkotlin/jvm/functions/Function2;)V
public final fun afterInvocation (Lkotlin/jvm/functions/Function3;)V
public fun afterSpec (Lkotlin/jvm/functions/Function2;)V
public fun afterTest (Lkotlin/jvm/functions/Function2;)V
public final fun appliedTags ()Ljava/util/Set;
Expand All @@ -63,6 +64,7 @@ public abstract class io/kotest/core/TestConfiguration {
public final fun beforeAny (Lkotlin/jvm/functions/Function2;)V
public final fun beforeContainer (Lkotlin/jvm/functions/Function2;)V
public final fun beforeEach (Lkotlin/jvm/functions/Function2;)V
public final fun beforeInvocation (Lkotlin/jvm/functions/Function3;)V
public final fun beforeSpec (Lkotlin/jvm/functions/Function2;)V
public fun beforeTest (Lkotlin/jvm/functions/Function2;)V
public final fun extension (Lio/kotest/core/extensions/Extension;)Lio/kotest/core/extensions/Extension;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,23 @@ import io.kotest.common.SoftDeprecated
import io.kotest.core.extensions.Extension
import io.kotest.core.extensions.TestCaseExtension
import io.kotest.core.listeners.AfterContainerListener
import io.kotest.core.listeners.AfterInvocationListener
import io.kotest.core.listeners.AfterTestListener
import io.kotest.core.listeners.BeforeContainerListener
import io.kotest.core.listeners.BeforeInvocationListener
import io.kotest.core.listeners.TestListener
import io.kotest.core.spec.AfterAny
import io.kotest.core.spec.AfterContainer
import io.kotest.core.spec.AfterEach
import io.kotest.core.spec.AfterInvocation
import io.kotest.core.spec.AfterSpec
import io.kotest.core.spec.AfterTest
import io.kotest.core.spec.AroundTestFn
import io.kotest.core.spec.AutoCloseable
import io.kotest.core.spec.BeforeAny
import io.kotest.core.spec.BeforeContainer
import io.kotest.core.spec.BeforeEach
import io.kotest.core.spec.BeforeInvocation
import io.kotest.core.spec.BeforeSpec
import io.kotest.core.spec.BeforeTest
import io.kotest.core.spec.Spec
Expand Down Expand Up @@ -246,6 +250,34 @@ abstract class TestConfiguration {
})
}

/**
* Registers a callback to be executed before every invocation of [TestCase]
* with type [TestType.Test].
*
* The [TestCase] about to be executed and invocation iteration is provided as the parameter.
*/
fun beforeInvocation(f: BeforeInvocation) {
register(object : BeforeInvocationListener {
override suspend fun beforeInvocation(testCase: TestCase, iteration: Int) {
f(testCase, iteration)
}
})
}

/**
* Registers a callback to be executed after every invocation of [TestCase]
* with type [TestType.Test].
*
* The [TestCase] about to be executed and invocation iteration is provided as the parameter.
*/
fun afterInvocation(f: AfterInvocation) {
register(object : AfterInvocationListener {
override suspend fun afterInvocation(testCase: TestCase, iteration: Int) {
f(testCase, iteration)
}
})
}

/**
* Registers a callback to be executed after every [TestCase]
* with type [TestType.Container] or [TestType.Test].
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ typealias AfterEach = suspend (Tuple2<TestCase, TestResult>) -> Unit
typealias BeforeContainer = suspend (TestCase) -> Unit
typealias AfterContainer = suspend (Tuple2<TestCase, TestResult>) -> Unit
typealias BeforeAny = suspend (TestCase) -> Unit
typealias BeforeInvocation = suspend (TestCase, Int) -> Unit
typealias AfterAny = suspend (Tuple2<TestCase, TestResult>) -> Unit
typealias BeforeSpec = suspend (Spec) -> Unit
typealias AfterSpec = suspend (Spec) -> Unit
typealias AfterInvocation = suspend (TestCase, Int) -> Unit
typealias AfterProject = () -> Unit
typealias FinalizeSpec = suspend (Tuple2<KClass<out Spec>, Map<TestCase, TestResult>>) -> Unit
typealias TestCaseExtensionFn = suspend (Tuple2<TestCase, suspend (TestCase) -> TestResult>) -> TestResult
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class DiscoveryTest : FunSpec({
.build()
val engine = KotestJunitPlatformTestEngine()
val descriptor = engine.discover(req, UniqueId.forEngine("testengine"))
descriptor.classes.size shouldBe 26
descriptor.classes.size shouldBe 28
}

test("kotest should return classes if request has no included or excluded test engines") {
Expand All @@ -108,7 +108,7 @@ class DiscoveryTest : FunSpec({
.build()
val engine = KotestJunitPlatformTestEngine()
val descriptor = engine.discover(req, UniqueId.forEngine("testengine"))
descriptor.classes.size shouldBe 25
descriptor.classes.size shouldBe 27
}

test("kotest should support include package name filter") {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.sksamuel.kotest.runner.junit5

import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import org.junit.platform.engine.discovery.DiscoverySelectors
import org.junit.platform.testkit.engine.EngineTestKit

class InvokeAfterInvocationTest : FunSpec({
test("should execute all afterInvocation blocks") {
EngineTestKit.engine("kotest")
.selectors(DiscoverySelectors.selectClass(AfterInvocationExample::class.java))
.configurationParameter("allow_private", "true")
.execute()

AfterInvocationExample.count shouldBe 30
}
})

private class AfterInvocationExample : FunSpec() {

companion object {
var count = 0
}

init {
afterInvocation { _, _ -> count++ } // adds +1 10 times
afterInvocation { _, _ -> count++ } // adds +1 10 times
test("my case").config(invocations = 10) {
count++ // adds +1 10 times
true shouldBe true
} // should be 30 in total
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.sksamuel.kotest.runner.junit5

import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import org.junit.platform.engine.discovery.DiscoverySelectors
import org.junit.platform.testkit.engine.EngineTestKit

class InvokeBeforeInvocationTest : FunSpec({
test("should execute all beforeInvocation blocks") {
EngineTestKit
.engine("kotest")
.selectors(DiscoverySelectors.selectClass(BeforeInvocationExample::class.java))
.configurationParameter("allow_private", "true")
.execute()

BeforeInvocationExample.count shouldBe 30
}
})

private class BeforeInvocationExample : FunSpec() {

companion object {
var count = 0
}

init {
beforeInvocation { _, _ -> count++ } // adds +1 10 times
beforeInvocation { _, _ -> count++ } // adds +1 10 times
test("my case").config(invocations = 10) {
count++ // adds +1 10 times
true shouldBe true
} // should be 30 in total
}
}

0 comments on commit 7727acf

Please sign in to comment.