本文介绍了为Spek使用JUnit5标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将我的测试区分为单元测试和集成测试。
我的想法是使用新的JUnit5 Annotation

关于如何将Spek和JUnit5标签或其他想法集成到单元测试和集成测试中的想法?

解决方案

今天我跑完全一样的问题。我必须将测试分为3个部分:单元,服务(测试REST API)和集成(WebDriver)。



Disclamer:适用于任何测试框架,不仅适用于 Spek 。 Gradle 4.6 或更新版本才能运行。

将测试源集合分成源集在我的例子中,它们是:


  • <$ c $

    c> src / test - 对于单元测试(您已经拥有它)


  • src / serviceTest - 用于服务测试
  • src / integrationTest - 用于集成测试



所有这些集合都应该有标准的源集合结构。在您的项目中创建这些文件夹并将您的软件包移动到相应的源集。

完成后,在依赖部分 $ c $>以下行:

  sourceSets {
integrationTest {
compileClasspath + = main.output
runtimeClasspath + = main.output
}
serviceTest {
compileClasspath + = main.output
runtimeClasspath + = main.output
}
}

配置{
integrationTestCompile.extendsFrom testCompile
integrationTestRuntime.extendsFrom testRuntime

serviceTestCompile.extendsFrom testCompile
serviceTestRuntime.extendsFrom testRuntime
}

执行此操作后,您的IDE(我想你使用Idea)应重新索引 build.gradle 并识别源集。您的新来源集可能有错误,因为他们没有看到其他来源。这是正确的,因为这些源集意在独立运行,而且不应该是一个问题。



将依赖关系分隔为适当的配置(可选)

缺省值 serviceTest 和 integrationTest 继承所有 test 依赖关系,但是如果您需要将某些特定配置移出通用范围,则可以在此处执行此操作。 在我的情况下, WebDriver 非常重,除了集成测试之外,我不需要它。

 依赖关系{
//可用于所有作用域
testCompileorg.jetbrains.spek:spek- api:$ spekVersion
testRuntimeorg.jetbrains.spek:spek-junit-platform-engine:$ spekVersion
testCompileorg.junit.platform:junit-platform-launcher:$ junitPlatformVersion

//仅编译integrationTest
integrationTestCompileorg.seleniumhq.selenium:selenium-java:3.11.0
integrationTestCompileorg.seleniumhq.selenium.fluent:fluent-selenium :1.19

安装程序执行顺序



我们需要添加测试类型的gradle任务并设置它。您可以为不同的测试任务设置不同的设置。

  task serviceTest(type:Test){
//运行测试从src / serviceTest
testClassesDirs = sourceSets.serviceTest.output.classesDirs
classpath = sourceSets.serviceTest.runtimeClasspath
}
//安装serviceTest任务
serviceTest {
//如果您需要在第一次失败后跳过集合中的测试,请取消注释。由于Gradle 4.6
// failFast = true

//启用某些日志记录
testLogging {
eventsPASSED,FAILED,SKIPPED
}

//启用JUnit5测试
useJUnitPlatform {
}
}

对integrationTest执行相同操作。

最后,设置依赖项和执行顺序:

  //在gradle检查期间运行服务测试
check.dependsOn serviceTest
check.dependsOn integrationTest

//在单元测试后运行服务测试
serviceTest.mustRunAfter测试
//在服务测试后运行集成测试
integrationTest.mustRunAfter serviceTest

结论



您将获得:


  1. 的单位 - 单位 - >服务 - >集成测试套件以严格顺序运行;
  2. 如果测试失败(不管 failFast 选项),其余的将不会运行并浪费资源;
  3. 能够在执行 gradle< task>

其他资源:


  • 以下是,它使用 Spek

  • 介绍了很多与测试相关的内容。


I am trying to distinguish my tests into Unit- and Integration tests.My idea was to use the new JUnit5 Annotation @Tag("unit") which works nicely for my JUnit tests, but I cannot get it to work with Spek.

What I currently have is my class:

data class MyObject(val value: Int)

My tests:

@Tag("unit")
object MyObjectTest {

    @Test
    fun checkEquality() {
        val o1 = MyObject(1)
        assertEquals(o1, o1)
    }
}

With my build.gradle having:

task utest(type: Test) {
    outputs.upToDateWhen { false }
    useJUnitPlatform {
        includeEngines 'junit-jupiter', 'junit-vintage', 'spek'
        includeTags 'unit'
        excludeTags 'performance', 'integration', 'functional'
    }


    testLogging {
        events "passed", "skipped", "failed"
    }
}

When I execute utest, this works.However when doing the same with Spek:

@Tag("unit")
object MyObjectSpek : Spek({

   given("an Object") {
       val o1 = MyObject(1)

       it("should be equal to itself") {
           assertEquals(o1, o1)
       }
   }
})

What happens is if I run the gradle task utest it only executes the methods from MyObjectTest and does not execute the tests for MyObjectSpek

Any ideas on how to integrate Spek with JUnit5 Tags or another idea to seperate unit tests and integration tests?

解决方案

today I ran exactly into the same problem. I had to separate tests into 3 sections: Unit, Service (testing REST API) and Integration (WebDriver).

Disclamer: this guide is applicable for any testing framework, not only to Spek. Gradle 4.6 or newer is required to run this.

Separate test source set into source sets

In my example they would be:

  • src/test — for Unit tests (you already have it)
  • src/serviceTest — for Service tests
  • src/integrationTest — for Integration tests

all these sets should have standard source set structure. Create these folders inside your project and move your packages to corresponding source sets.

When it is done add to build.gradle before dependency section following lines:

sourceSets {
    integrationTest {
        compileClasspath += main.output
        runtimeClasspath += main.output
    }
    serviceTest {
        compileClasspath += main.output
        runtimeClasspath += main.output
    }
}

configurations {
    integrationTestCompile.extendsFrom testCompile
    integrationTestRuntime.extendsFrom testRuntime

    serviceTestCompile.extendsFrom testCompile
    serviceTestRuntime.extendsFrom testRuntime
}

After you do this your IDE (I suppose you use Idea) should reindex build.gradle and recognize source sets. You may have errors in your new source sets because they do not see each other sources. That's correct, because these source sets intended to run independently, and should not be a problem.

Separate dependencies to appropriate configurations (Optional)

By default serviceTest and integrationTest inherit all test dependencies, but if you need to move something specific to certain configuration out of common scope, you can do this here.

In my case WebDriver is quite heavy and I do not need it anywhere except integration testing.

dependencies {
    // available for all scopes
    testCompile "org.jetbrains.spek:spek-api:$spekVersion"
    testRuntime "org.jetbrains.spek:spek-junit-platform-engine:$spekVersion"
    testCompile "org.junit.platform:junit-platform-launcher:$junitPlatformVersion"

    // compiles only for integrationTest
    integrationTestCompile "org.seleniumhq.selenium:selenium-java:3.11.0"
    integrationTestCompile "org.seleniumhq.selenium.fluent:fluent-selenium:1.19"
}

Setup execution order

We will need to add gradle task of Test type and setup it. You can have different settings for different test tasks.

task serviceTest(type: Test) {
    // Runs tests from src/serviceTest
    testClassesDirs = sourceSets.serviceTest.output.classesDirs
    classpath = sourceSets.serviceTest.runtimeClasspath
}
// Setup serviceTest task
serviceTest {
    // Uncomment this if you need to skip tests from the set after first failure. Since Gradle 4.6
    //failFast = true

    // Enable some logging
    testLogging {
        events "PASSED", "FAILED", "SKIPPED"
    }

    // Enable JUnit5 tests
    useJUnitPlatform {
    }
}

Do the same for integrationTest.

Finally, setup the dependencies and order of execution:

// Make service tests run during gradle check
check.dependsOn serviceTest
check.dependsOn integrationTest

// Make service tests run after unit tests
serviceTest.mustRunAfter test
// Make integration tests run after service tests
integrationTest.mustRunAfter serviceTest

Conclusion

You will get:

  1. Chain of Unit -> Service -> Integration test suites running in strict order;
  2. If you will get a test failure (regardless of failFast option) in one test suite, the remaining won't run and waste resources;
  3. Ability to run from console each suite separately within execution of gradle <task>.

Additional resources:

这篇关于为Spek使用JUnit5标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-03 19:48
查看更多