Jenkins 中带有 Dockerized DB 的 Java 集成测试





3.00/5 (2投票s)
Travis 中的集成测试,为 PR 提供覆盖反馈。
引言
本文将介绍如何在 Jenkins 中使用 Docker 化数据库来设置集成测试。在 CI 流水线中执行集成测试非常重要,这样可以及时发现 CI 本身的任何错误。由于集成测试依赖于数据库和其他服务,因此我们需要在 CI 中安装这些服务。如果您的应用程序有很多依赖项,安装特定版本将会很繁琐。但通过 Docker,可以简化这些依赖项。本文将介绍如何使用 Docker 化数据库来完成此操作。
免责声明
本文使用一种基于纯脚本的方式在 Jenkins 中运行集成测试。为演示目的,本文使用了 Spring 项目和 JUnit 5 测试用例。由于主要涉及测试用例和代码覆盖率,因此没有控制器或 API。
此外,本文主要侧重于设置集成测试和 Docker 化数据库,以及代码覆盖率反馈。我计划另写一篇文章来解释如何编写集成测试用例。
预设
现在,我们将进入预设部分。我选择了一个基于 Spring Boot 的项目。这是一个简单的员工 CRUD 应用程序。它有数据访问层和服务层。它包含一些验证,例如:
Employee
的电子邮件格式必须正确。- 更新
employee
时,必须获取现有的employee
ID。 - 更新时,不能使用另一个
employee
的现有电子邮件。 - 不存在的
employee
ID 不能被删除。
所有这些测试用例都使用新的 JUnit 5 编写。我已经在 这里 解释了 JUnit 5 的一些重要功能。我编写了集成测试来覆盖上述用例。此处 是源代码链接。
安装
Docker 可以通过 Docker 镜像或独立安装程序进行安装。在这里,我们选择独立安装程序,因为我们计划在 Docker 中运行依赖服务。由于在 Docker 中安装 Docker 可能会出现问题,因此我没有将 Jenkins 作为 Docker 镜像。
Jenkins 可在此处下载 - https://jenkins.io/download/。
安装 Jenkins 后,创建一个名为“java-int-test
”的新作业,并选择“自由风格项目”。设置如下:
Jenkins 作业有几个部分,如 SCM、构建频率、构建命令、构建后设置。我将详细解释这些。
SCM:这里应提供源代码的路径。由于我们将构建和运行测试用例,因此需要一些源代码作为起点。我们使用 GitHub,因此我选择了 Git。如果是私有仓库,您需要提供凭据,以便它可以获取源代码。设置如下:
构建频率:这里可以指定何时构建项目。我选择了每小时构建一次。也可以设置为每次提交到仓库时运行。这是我的设置:
构建命令:这是关键步骤,我们在此指定对我们获取的源代码要执行的命令。这是我的设置:
由于我们运行的是 Docker 化数据库,因此需要在 Jenkins 运行的系统上安装 Docker。此外,我们使用 MariaDB(MySQL 的变种)作为集成测试的数据库,因此也需要在与 Jenkins 相同的机器上安装 MySQL 客户端,因为在测试运行之前我们需要应用数据库脚本。
这些命令如下:
docker stop testdb || true
docker rm testdb || true
docker run --name testdb -p 4306:3306 -e MYSQL_ROOT_PASSWORD=root -d mariadb/server:10.3
/bin/sleep 30s
mysql --host=127.0.0.1 --port=4306 --user="root" -proot
--execute="CREATE SCHEMA IF NOT EXISTS demo_test;"
mysql --host=127.0.0.1 --port=4306 --user="root"
-proot demo_test < src/main/resources/migration/V1.1__create_employee_table.sql
mysql --host=127.0.0.1 --port=4306 --user="root"
-proot demo_test < src/main/resources/migration/V1.2__seed_employees.sql
mysql --host=127.0.0.1 --port=4306 --user="root" -proot -e "select * from demo_test.Employee"
./gradlew clean build test
我将在下面解释上面的命令。
- 目前,请忽略前两行,稍后会解释。
- 第三行,我们正在拉取版本为 10.3 的 MariaDB 服务器,主机端口映射为 4306,MySQL root 密码设置为 root。这将创建一个名为
testdb
的容器。 - 由于容器初始化需要一些时间,因此必须等到它启动,所以我设置了 30 秒的睡眠时间。
- 现在我们的数据库已启动并运行,在第 4-7 行,我们正在连接到数据库以执行各种活动,例如:创建空白 schema、应用数据库脚本并验证一切是否正常运行。如果您注意到,要连接到 Docker 容器数据库,我们使用了 MySQL
--host=127.0.0.1 --port=4306 --user="root" -proot
,这里我们使用了在第三行设置的端口和凭据 root / root。 - 最后一行,我们正在构建项目并运行测试。
- 前两行实际上是执行容器清理。这样,我们的测试是可重复的,每次运行,我们都会获得一个干净的容器和一个干净的数据库。
在测试应用程序属性中,它指向测试数据库。这是设置文件:
# ===============================
# = DATA SOURCE
# ===============================
# Set here configurations for the database connection
spring.datasource.url=jdbc:mariadb://:4306/demo_test
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
# Keep the connection alive if idle for a long time (needed in production)
spring.datasource.testWhileIdle=true
spring.datasource.validationQuery=SELECT 1
代码覆盖率设置
我使用了 jacoco
gradle
插件来获取代码覆盖率报告。
id 'jacoco'
test {
useJUnitPlatform()
finalizedBy jacocoTestReport
}
要发布 Jenkins 中的代码覆盖率报告,我使用了插件 - "JUnit Realtime Test Reporter Plugin" 和 "JaCoCo Plugin"。要安装它们,请转到“Manage Jenkins” -> “Manage Plugins” -> 单击“Available”选项卡 -> 搜索上述两个插件。然后选择它们并安装。这需要重启 Jenkins,请继续操作。
下一步是配置这些插件以读取我们的测试报告并将其漂亮地发布到 Jenkins。
这是 JUnit 测试 XML 的设置。由于我们的测试 XML 文件创建在 `build/test-results/test/` 下,所以我在这里给出了该路径。
这是 Jacoco 的设置。我没有做任何更改,这是默认设置。
完成所有这些设置后,导航到我们创建的作业,然后在左侧单击“build now”。之后,您会看到一个构建号,如下所示:
单击最近的构建号,然后单击“Console output”。在那里,您可以看到所有正在运行的命令。如果一切成功,它应该会像上面的屏幕截图一样显示为蓝色。
成功运行后,代码覆盖率报告如下所示。它将为您提供所有类型的覆盖率,如类、行、方法等。
这是单元测试报告。
您可以在此处浏览所有测试用例的执行情况。您还可以看到还有多少行需要覆盖等。
关注点
在代码覆盖率和集成测试方面,有很多工作可以做。我在这里列出了一些。如果您的应用程序依赖于其他服务,您可以向 Jenkins 构建过程添加更多依赖项,例如:数据库、缓存、Solr、队列服务等。在代码覆盖率方面,Gradle 提供了许多选项,例如在代码覆盖率未达到特定百分比时将构建标记为失败,还可以有很多其他选项。
历史
这是我最初发布的内容。我将在此处保留修订列表。
- 修订 1:首次发布
- 修订 2:添加了 Jenkins 和 Docker 化数据库设置