Update在搜索最优解决方案时,临时切换到一种使用专用测试工厂的方法,该工厂与forAll一起执行init。这样,我就不必在每个测试工厂中重复init代码。
fun somePreStuffFactory() = funSpec {
beforeTest {
println("Do some init stuff here")
}
test("dummy test just to trigger beforeTest") {}
}
class MyTest : FunSpec({
runBlocking {
forAll(
row(MyTestFactory::someTest1),
row(MyTestFactory::someTest2)
) { testFactoryFunc ->
include(somePreStuffFactory())
include(testFactoryFunc())
}
}
})更新结束
我在测试工厂里做了很多测试。在测试工厂内运行测试之前,我需要在每个测试工厂的开头做一些初步的设置,对于所有的测试工厂,设置是相同的。
问题是在测试工厂中没有调用beforeSpec,因此我目前正在通过在每个测试工厂的第一个测试中执行init来使用一种肮脏的解决方法。我非常感谢你对此提出任何建议。
最佳解决方案是在每个测试工厂之前运行的测试类中有一个生命周期挂钩。
代码复制
class MyTest : FunSpec({
include(someTest1())
include(someTest2())
})import io.kotest.core.spec.style.funSpec
object MyTestFactory {
fun someTest1() = funSpec {
beforeSpec {
/** Not invoked */
println("Hello from someTest1#beforeSpec")
}
test("Init stuff is done inside a test") {
/** some init here */
}
test("first test") {
println("Hello from first test")
}
test("second test") {
println("Hello from second test")
}
}
fun someTest2() = funSpec {
beforeSpec {
/** Not invoked */
println("Hello from someTest2#beforeSpec")
}
test("Init stuff is done inside a test") {
/** some init here */
}
test("third test") {
println("Hello from third test")
}
}
}我到目前为止尝试过的
在将Kotest从4.6.4跳到5.4.2之后,我能够运行@ocos的应答代码。问题是,BeforeSpecSample#beforeSpec只被调用一次,而不是对每个测试工厂调用一次,这是我的要求。
object BeforeSpecSample : BeforeSpecListener {
override suspend fun beforeSpec(spec: Spec) {
println("Hello from beforeSpec")
}
}
class MyTest : FunSpec({
extensions(BeforeSpecSample)
include(someTest1())
include(someTest2())
})Update在阅读这个GitHub问题之后,使用布尔变量initialized和beforeTest成功地测试了以下方法。如果这种方法可以在测试类中使用,而不是在每个测试工厂中使用,那就太好了,但是如果没有测试工厂的生命周期挂钩,我看不出这是怎么做到的。
fun someTest1() = funSpec {
var initialized = false
beforeTest {
if (!initialized) {
println("Hello from someTest1#beforeTest")
initialized = true
}
}
/** tests goes here */
}Environment Kotest 4.6.4,Kotlin 1.7.10,Micronaut 3.6.3
发布于 2022-09-20 18:24:20
如果您不介意将测试工厂中的所有内容分组到context块中,则可以使用BeforeContainerListener进行初始化:
object InitExtension : BeforeContainerListener {
override suspend fun beforeContainer(testCase: TestCase) {
if(testCase.parent == null) {
println("init stuff")
}
}
}if(testCase.parent == null)只是为了允许工厂拥有其他嵌套的context,这些嵌套context不会触发初始化的额外调用。
然后你可以这样写你的工厂:
fun someTest1() = funSpec {
extension(InitExtension)
context("someTest1") {
test("first test") {
println("Hello from first test")
}
test("second test") {
println("Hello from second test")
}
}
}InitExtension中的初始化将在context someTest1开始时调用,并且可以类似地包含在可以由同一个扩展初始化的其他测试工厂中。
发布于 2022-09-16 15:25:01
include只使用在someTest()的TestFactory中定义的测试和扩展,这就是为什么beforeSpec没有被调用的原因。
您可以在您的extension中注册MyTest。下面是一个例子。
// you may use object MyTestFactory : BeforeSpecListener
object BeforeSpecSample : io.kotest.core.listeners.BeforeSpecListener {
override suspend fun beforeSpec(spec: Spec) {
println("-> before spec <-")
}
}
class MyTest : FunSpec({
extensions(BeforeSpecSample)
include(someTest())
test("my test 1") { println("my test 1") }
})https://stackoverflow.com/questions/73746567
复制相似问题