因为Java项目的标准项目布局仅定义了一个测试目录( src / test ),所以我们没有将集成测试添加到Gradle构建中的标准方法。

如果要使用标准项目布局,则可以使用以下选项之一将集成测试添加到Gradle构建中:

  • 我们可以将集成测试添加到与单元测试相同的目录中。 这是一个糟糕的主意,因为集成测试通常比单元测试慢很多。 如果我们决定使用这种方法,则反馈循环的长度比应该的要长得多。
  • 我们可以创建一个新项目,并将集成测试添加到该项目中。 这没有任何意义,因为它迫使我们将项目转换为多项目构建。 另外,如果我们的项目已经是多项目构建,那么我们就被搞砸了。 当然,我们可以将所有集成测试添加到同一项目中,也可以为每个经过测试的项目创建新的集成测试项目,但是脚踏实地的工作会比较轻松。

显然,我们需要一种更好的方法 。 这篇博客文章描述了我们如何创建满足以下要求的Gradle构建:

  • 集成测试和单元测试必须具有不同的源目录。 src / integration-test / java目录必须包含我们的集成测试的源代码,而src / test / java目录必须包含我们的单元测试的源代码。
  • 集成测试和单元测试必须具有单独的资源目录。 src / integration-test / resources目录必须包含我们的集成测试的资源。 src / test / resources目录必须包含我们的单元测试的资源。
  • 我们必须能够为集成测试配置编译时和运行时依赖项。
  • 我们必须能够运行我们的单元测试或集成测试。
  • 我们必须能够运行所有测试。
  • 如果集成测试失败,我们的构建也必须失败。
  • 集成测试和单元测试必须具有单独HTML报告。

让我们从配置集成测试的源目录和资源目录开始。

配置我们的集成测试的源目录和资源目录

我们可以使用sourceSets构建脚本块将新的源和资源目录添加到Gradle构建中。 有了这些信息,我们可以按照以下步骤配置集成测试的源目录和资源目录:

  1. 创建一个名为IntegrationTest的新源集。
  2. 确保将主源集和测试源集的输出添加到编译时类路径中。
  3. 确保将主要和测试源集的输出添加到运行时类路径。
  4. 将我们的集成测试的源目录设置为src / integration-test / java 。
  5. 将集成测试的资源目录设置为src / integration-test / resources 。

完成后,在存储库构建脚本块之后 ,我们的build.gradle文件应具有以下sourceSets构建脚本块:

sourceSets {
    integrationTest {
        java {
            compileClasspath += main.output + test.output
            runtimeClasspath += main.output + test.output
            srcDir file('src/integration-test/java')
        }
        resources.srcDir file('src/integration-test/resources')
    }
}

补充阅读:

  • 第23.2节Java插件– Gradle用户指南的源集
  • sourceSets构建脚本块的DSL参考
  • SourceSetOutput的DSL参考

当在命令提示符处运行命令: gradle properties时,我们将看到一长串项目属性。 与该博客文章相关的属性如下所示:

> gradle properties
:properties

------------------------------------------------------------
Root project
------------------------------------------------------------
configurations: [configuration ':archives', configuration ':compile', configuration ':default', configuration ':integrationTestCompile', configuration ':integrationTestRuntime', configuration ':runtime', configuration ':testCompile', configuration ':testRuntime']

sourceSets: 1
sources: [Java source 'main:java', JVM resources 'main:resources', Java source 'test:java', JVM resources 'test:resources', Java source 'integrationTest:java', JVM resources 'integrationTest:resources']

BUILD SUCCESSFUL

Total time: 3.34 secs

如我们所见,我们在Gradle构建中添加了新的源和资源目录。 有趣的是,当我们创建一个新的源集时,Java插件向我们的构建中添加了两个新的依赖项配置:

  • IntegrationTestCompile配置用于声明编译我们的集成测试时所需的依赖项。
  • IntegrationTestRuntime配置用于声明运行我们的集成测试所需的依赖项。 此配置包含添加到integrationTestCompile配置中的所有依赖项。

补充阅读:

  • 第23.5节Java插件– Gradle用户指南的依赖性管理

让我们继续前进,找出在这些依赖项配置对我们有用之前必须进行哪些配置更改。

配置我们的集成测试的依赖项配置

在配置集成测试的源目录和资源目录时,我们创建了一个源集,该源集创建了两个新的依赖项配置: IntegrationTestCompile和IntegrationTestRuntime 。 问题在于这些配置不包含我们的单元测试的依赖项。

我们可以通过向这些配置中添加所需的依赖项来解决此问题,但是由于添加重复的配置是一个糟糕的主意,因此我们不会这样做。 相反,我们将按照以下步骤配置这些依赖项配置:

  1. 确保IntegrationTestCompile配置包含编译我们的单元测试所需的依赖项。
  2. 确保IntegrationTestRuntime配置包含运行我们的单元测试所需的依赖项。

我们可以使用配置构建脚本块进行这些更改。 换句话说,我们必须将下面的代码添加到sourceSets和依赖关系构建脚本块之间我们的build.gradle文件:

configurations {
    integrationTestCompile.extendsFrom testCompile
    integrationTestRuntime.extendsFrom testRuntime
}

补充阅读:

  • Gradle用户指南的8.3节依赖项配置
  • 配置构建脚本块的DSL参考
  • ConfigurationContainer的DSL参考
  • 配置的DSL参考

现在,我们可以向这些配置添加依赖项。 例如,如果要在集成测试中使用AssertJ 3.0 ,则必须将assertj-core依赖项添加到integrationTestCompile配置中。 完成此操作后,从build.gradle文件中找到的依赖项构建脚本块如下所示:

dependencies {
    compile 'log4j:log4j:1.2.17'
    testCompile 'junit:junit:4.11'
    integrationTestCompile 'org.assertj:assertj-core:3.0.0'
}

补充阅读:

  • Gradle入门:依赖管理

下一步是创建运行集成测试的任务。 让我们找出如何做到这一点。

创建运行我们的集成测试的任务

我们可以按照以下步骤创建运行集成测试的任务:

  1. 创建一个名为IntegrationTest的新任务,并将其类型设置为Test 。
  2. 配置已编译测试类的位置。
  3. 配置运行我们的集成测试时使用的类路径。

通过将以下代码添加到我们的build.gradle文件中,我们可以创建和配置integrationTest任务:

task integrationTest(type: Test) {
    testClassesDir = sourceSets.integrationTest.output.classesDir
    classpath = sourceSets.integrationTest.runtimeClasspath
}

补充阅读:

  • 第15.1节《 Gradle用户指南》中的定义任务
  • 任务的DSL参考

我们已经创建了运行集成测试的任务,但是问题是在构建期间未调用此任务。 因为要将其包含在我们的构建中,所以我们必须遵循以下步骤:

  1. 确保集成测试在检查任务之前运行,并且如果集成测试失败,则检查任务会使构建失败。
  2. 确保在集成测试之前运行我们的单元测试。 即使我们的集成测试失败,这也可以确保我们的单元测试得以运行。

我们可以通过将以下行添加到build.gradle文件中来进行这些配置更改:

check.dependsOn integrationTest
integrationTest.mustRunAfter test

补充阅读:

  • 第23.3节Java插件– Gradle任务用户指南
  • 第15.4节为Gradle用户指南的任务添加依赖项
  • Gradle用户指南的15.5节订购任务

我们差不多完成了,但是仍然有一个问题。 我们的单元测试和集成测试将它们HTML报告创建到同一报告目录。 这意味着,如果我们同时运行单元测试和集成测试,则只能看到包含集成测试的测试结果HTML报告。

通过将以下代码段添加到我们的build.gradle文件中,我们可以确保将单元测试和集成测试HTML报告创建到不同的报告目录:

tasks.withType(Test) {
    reports.html.destination = file("${reporting.baseDir}/${name}")
}

这不是我自己的想法。 我是从这个Stackoverflow答案中借用的,它解释了如何创建用于集成和单元测试的单独HTML报告。

在将此代码段添加到build.gradle文件中之后,我们的单元测试和集成测试将使用它们自己的报告目录,如下所述:

  • build / reports / integrationTest目录包含HTML报告,该报告包含我们的集成测试的测试结果。
  • build / reports / test目录包含HTML报告,该报告包含我们的单元测试的测试结果。

我们完了! 让我们继续前进,找出如何运行测试。

运行我们的测试

现在,我们创建了一个运行集成测试的新任务,并将该任务与Gradle构建集成在一起。 我们终于准备好运行我们的单元和集成测试。 我们的Gradle构建要求指出:

  • 我们必须能够运行唯一的单元测试。
  • 我们必须只能运行集成测试。
  • 我们必须能够运行所有测试。

让我们一一满足这些要求。

首先 ,如果我们只想运行单元测试,则可以使用以下两个选项之一:

  • 我们可以通过运行以下命令来运行单元测试: gradle clean test在命令提示符处。
  • 我们可以通过运行以下命令来运行构建并排除集成测试:在命令提示符下执行gradle clean build -x integrationTest 。

其次 ,如果我们只想运行集成测试,则可以选择以下选项之一:

  • 我们可以通过运行以下命令来运行集成测试: gradle clean integrationTest -x在命令提示符下进行测试 。
  • 我们可以通过运行以下命令来运行构建并排除单元测试: gradle clean build -x test在命令提示符处。

第三 ,如果要运行所有测试,我们可以选择以下两个选项之一:

  • 我们可以通过运行以下命令来运行单元测试和集成测试: gradle clean IntegrationTest在命令提示符下。
  • 我们可以通过运行以下命令来运行构建: gradle clean build在命令提示符处。

补充阅读:

  • 11.2节不包括Gradle用户用户指南的任务

让我们总结一下我们从此博客文章中学到的知识。

摘要

这篇博客文章告诉我们以下内容:

  • 如果我们向构建中添加新的源集,则Java插件会为其创建编译时间和运行时依赖项配置。
  • 我们可以使用Configuration的extendFrom属性来包含另一个依赖项配置的依赖项。
  • 我们可以通过创建一个新的Test任务,并配置集成测试类和使用的类路径的位置来创建一个运行集成测试的任务。
  • 我们可以向任务添加依赖项,并配置调用任务的顺序。
  • 我们可以使用-x命令行选项排除任务。
  • PS:您可以从Github获得此博客文章的示例应用程序 。

如果您想学习如何使用Gradle,请阅读我的Gradle教程 。

翻译自: https://www.javacodegeeks.com/2015/05/getting-started-with-gradle-integration-testing.html