测试 Java 应用

优质
小牛编辑
137浏览
2023-12-01

一些开源的测试框架比如 JUnit,TestNG 能够帮助你编写可复用的结构化的测试,为了运行这些测试,你要先编译它们,就像编译源代码一样。测试代码的作用仅仅用于测试的情况,你可不想把你的测试代码发布到生产环境中,把源代码和测试代码混在一起可不是个好主意。通常你会把源代码和测试代码分开来,比如 Gradle 的标准项目布局 src/main/java 和 src/test/java。

项目布局

在前面我们讲到默认的项目布局,源代码是 src/main/java,资源文件是在 src/main/resources,测试源代码路径也是这样,你把测试代码放在 src/test/java,资源文件放在 src/test/resources,编译之后测试的 class 文件在 build/classes/test 下。

所有的测试框架都会生成至少一个文件用来说明测试执行的结果,最普遍的格式就是 XML 格式,你可以在 build/test-results 路径下找到这些文件,XML 文件的可读性比较差,许多测试框架都允许把测试结果转换成报告,比如 JUnit 可以生成 HTML 格式的报告,Gradle 把测试报告放在 build/reports/test。下图清晰的显示了项目的布局:

上面讲了这么多测试框架,Gradle 怎么知道你想使用哪一个呢?你需要声明对外部库的依赖。

测试配置

Java 插件引入了两个配置来声明测试代码的编译期和运行期依赖 testCompile 和 testRuntime,我们来看一下怎么声明一个对 JUnit 框架的编译期依赖:

dependencies {
    testCompile 'junit:junit:4.11'
}

另外一个配置 testRuntime 用来声明那些编译期用不着但是在运行期需要的依赖,记住用于测试的依赖不会影响你源代码的 classpath,换句话说他们不会用在编译或打包过程。然而,对于处理依赖来讲测试配置继承了源代码相关配置,比如 testCompile 继承了 compile 配置的依赖,testRuntime 继承了 runtime 和 testCompile 和他们的父类,他们父类的依赖会自动传递到 testCompile 或 testRuntime 中。如下图所示:

测试任务

在之前的任务我们可能注意到任务图一直有四个任务是 up-to-date 的然后被跳过了,这是因为你没有编写任何测试代码 Gradle 就不需要编译或执行。下图显示了这四个任务在任务图中的位置:

从图中可以看到测试编译和测试执行阶段是在源代码被编译和打包之后的,如果你想避免执行测试阶段你可以在命令行执行 gradle jar 或者让你的任务依赖 jar 任务。

自动测试检查

对于 build/classes/test 目录下的所有编译的测试类,Gradle 怎么知道要执行哪一个呢?答案就是所有匹配下面几条描述的都会被检查:

  • 任何继承自 junit.framework.TestCase 或 groovy.util.GroovyTestCase 的类
  • 任何被 @RunWith 注解的子类
  • 任何至少包含一个被 @Test 注解的类

如果没有找到符合条件的,测试就不会执行,接下来我们会使用不同框架来编写单元测试。