如何实施在 jenkins 部署后执行的 gradle 系统测试?

how to implement gradle system test that get executed after a jenkins deployment?

我有一个 gradle 项目,由 Jenkins 按照以下步骤构建:

  1. 构建项目,运行 单元和集成测试
  2. 构建并发布 docker 个图像
  3. 将应用程序部署到预生产
  4. 运行 预生产系统测试
  5. 将应用程序部署到生产环境

现在第4步还没有准备好,我想知道如何以最方便的方式实现它..?

我想使用 JUnit5,测试应该在项目本身内部进行,因此要么在其中一个模块中,要么与一个单独的模块一起使用,该模块也包含在内并且有一些其他模块作为依赖项。

当我创建一个带有常规 JUnit5 测试的单独模块时,这些测试会在步骤 1 中自动执行。所以我想要实现的是这些系统测试的自定义 gradle 步骤。

这样做的一个好方法是实施一个新的 gradle 任务和一个同名的新源集——例如“systemTest”。这是具有简单系统测试的多模块 gradle 项目的示例代码:

我的文件层次结构:

├── application
│   ├── build.gradle
│   └── src
│       ├── main
│       │   └── java
│       │       └── de
│       │           └── mycompany
│       │               └── mydepartment
│       │                   └── projectname
│       │                       └── Application.java
│       └── test
│           └── java
│               └── de
│                   └── mycompany
│                       └── mydepartment
│                           └── projectname
│                               └── ApplicationTest.java
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── Jenkinsfile
├── settings.gradle
└── systemtests
    ├── build.gradle
    └── src
        └── systemTest
            └── java
                └── de
                    └── mycompany
                        └── mydepartment
                            └── projectname
                                └── SystemTest.java

Application.java 包含我的业务逻辑(应该以某种方式将应用程序部署到 docker 或其他)。

ApplicationTest.java 是 JUnit5 单元测试,在构建过程中将 运行。

SystemTest.java 是 JUnit5 测试,旨在 运行 部署后。我们可以通过 ./gradlew systemTest.

执行此操作(如果将命令添加到构建脚本中,则手动或自动执行)

现在让我们看一下 gradle 个文件:

build.gradle (root):

subprojects {
    apply plugin: 'java'

    repositories {
        maven {
            name 'Nexus-Internal Access'
            url 'http://m2repo.system.local/content/groups/full/'
        }
    }

    dependencies {
        testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.6.0'
        testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.6.0'
    }

    sourceSets {
        main {
            java { output.resourcesDir = outputDir }
        }
        test {
            java { output.resourcesDir = outputDir }
        }
    }

    test {
        useJUnitPlatform()
    }
}

settings.gradle (root):

rootProject.name = 'service'

include 'application'
include 'systemtests'

application/build.gradle:

apply plugin: 'application'

application {
    mainClassName = 'de.mycompany.mydepartment.projectname.Application'
}

systemtests/build.gradle:

configurations {
    systemTestImplementation.extendsFrom testImplementation
}

sourceSets {
    systemTest {
        java { output.resourcesDir = outputDir }
    }

    jar.duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

task systemTest(type: Test) {
    useJUnitPlatform()
    group = 'verification'
    testClassesDirs = sourceSets.systemTest.output.classesDirs
    classpath = sourceSets.systemTest.runtimeClasspath
}

Jenkinsfile(为您提供灵感的未经测试的短语):

#!groovy

node {
    stage("Build") {
        sh """
            ./gradlew clean build
        """
    }
    stage("Build docker containers") {
        sh """
            docker build application
        """
    }
    stage("Deploy to pre-prod") {
        sh """
            oc rollout application to testserver
        """
    }
    stage("System Tests") {
        sh """
            ./gradlew clean systemTest --info
        """
    }
    stage("Deploy to prod") {
        sh """
            oc rollout application to prod
        """
    }
}

请注意,我在 /gradlew systemTest 任务上使用了 --info,这样我就可以在 Jenkins 控制台中读取来自系统测试的日志。我还使用系统属性将一些凭据从我们的 Jenkins 传递到 gradle。与 systemTest 任务的另一个 -Pname=${var} 参数。此处省略以免有人混淆:)