隆重推出 TestKit:用于功能测试 Gradle 构建逻辑的工具包

目录

  • 使用 TestKit
  • 了解更多关于 TestKit 的信息
  • TestKit 的路线图
  • 引言

    自动化测试是实现重构、持续集成和持续交付等软件开发实践的必要前提。虽然为应用程序代码编写单元测试、集成测试和功能测试已成为行业惯例,但不可否认的是,针对构建自动化领域的测试尚未普及。

    但为什么我们不对构建逻辑应用同样的成熟的测试实践呢?归根结底,构建逻辑与应用程序代码同等重要。它有助于我们以自动化、可重现和可靠的方式向客户交付生产软件。跳过测试可能有很多原因;然而,一个突出的原因是用于构建逻辑的数据定义格式。过去,在没有合适工具的情况下,为基于 XML 的构建逻辑定义编写测试是一项艰巨甚至几乎不可能完成的任务。

    在这方面,Gradle 让你的工作变得更容易。借助诸如自定义任务二进制插件之类的概念,构建代码可以得到妥善的组织,根据功能边界进行划分,并作为实际的类实现来开发。自动化构建逻辑测试变得触手可及,并且在与合适的工具结合时,很容易实现。

    认识 TestKit #

    测试构建逻辑的一种方法是像最终用户那样声明和执行它。在实践中,这意味着创建一个构建脚本,添加要测试的配置,然后使用 Gradle 运行时执行它。构建的结果,例如控制台输出、已执行的任务和生成的构件,可以被检查并与预期的断言进行验证。这种类型的测试通常被称为功能测试。

    让我们看一个例子。在下面的构建脚本中,我们应用了 Java 插件。

    build.gradle #

    apply plugin: 'java'
    

    使用 compileJava 任务执行此构建脚本,应为 `src/main/java` 目录中的 Java 源文件生成类文件。作为最终用户,我们期望这些类文件位于 `build/classes/main` 目录中。当然,您可以通过手动执行给定的构建脚本以及 Gradle 命令并检查输出目录来验证此行为。我希望最后一句话让你产生了某种冲动。我们是自动化工程师,所以显然我们希望尽可能自动化。

    隆重推出Gradle TestKit:一个用于以自动化方式执行功能测试的工具包。TestKit 自 2.6 版本起与 Gradle 一起打包,现已可供您在项目中使用。

    使用 TestKit #

    通常有两种不同的用例来将 TestKit 添加到项目中。

    1. 跨版本兼容性测试。您想验证构建脚本是否与特定 Gradle 版本兼容。组织通常在准备现有构建的 Gradle 版本升级或需要同一构建逻辑支持多个 Gradle 版本时应用此技术。

    2. 自定义构建逻辑测试。您想测试自定义任务或插件在类似于构建脚本作者的真实使用场景的特定条件下是否按预期工作。一个典型的例子可能是:“如果用户应用此插件并配置了我公开的扩展的属性,那么提供的任务应该观察到特定的运行时行为并在执行时产生输出 x。”在此场景之上,跨版本兼容性也可能发挥作用。

    考虑到最后一个例子,让我们来看看如何使用 TestKit API 实现这个场景。请注意,以下测试类使用了Spock 测试框架

    BuildLogicFunctionalTest.groovy #

    import org.gradle.testkit.runner.GradleRunner
    import static org.gradle.testkit.runner.TaskOutcome.*
    import org.junit.Rule
    import org.junit.rules.TemporaryFolder
    import spock.lang.Specification
    
    class BuildLogicFunctionalTest extends Specification {
       @Rule final TemporaryFolder testProjectDir = new TemporaryFolder()
       File buildFile
    
       def setup() {
           buildFile = testProjectDir.newFile('build.gradle')
       }
    
       def 'produces class files when compiling Java source code'() {
           given:
           buildFile << "apply plugin: 'java'"
    
           when:
           def result = GradleRunner.create()
               .withProjectDir(testProjectDir.root)
              .withArguments('compileJava')
              .build()
    
           then:
           result.task(':compileJava').outcome == SUCCESS
           new File(testProjectDir.root, 'build/classes/main').exists()
       }
    }
    

    即使您以前没有使用过 Groovy 或 Spock,也很容易发现借助 TestKit 可以构建一个功能测试用例。

    了解更多关于 TestKit 的信息 #

    上一个代码示例使用 Spock 来实现测试用例。如果您不熟悉 Spock 或偏好其他测试框架,仍然可以使用 TestKit。根据设计,TestKit 是与测试框架无关的。您可以根据自己的舒适度选择测试框架,无论是JUnitTestNG 还是其他任何现有的测试框架。

    对于需要使用多个 Gradle 分发版执行测试的测试场景(例如,在跨版本兼容性测试的上下文中),TestKit 会公开 API 方法来提供适当的 Gradle 分发版信息。您可以指向 Gradle 的本地安装、由 Gradle Inc. 托管的服务器上通过版本标识的分发版,或者通过 URI 标识的分发版。

    在执行测试时,您可能还想从您选择的 IDE 逐步调试被测试的构建逻辑。TestKit 允许您以调试模式执行测试,以跟踪意外的测试运行时行为。

    TestKit 的路线图 #

    TestKit 还有更多功能。未来,我们希望使 TestKit API 的使用更加便捷。您可以在设计文档中阅读所有相关内容。如果您有兴趣做出贡献,请告诉我们!我们很乐意看到 TestKit 的发展。

    讨论