Apache AntUnit
Apache AntUnit™
Apache AntUnit 是一个 Antlib,它为 Apache Ant 任务和类型提供了一个测试框架。
Apache AntUnit 1.4.1
2021 年 7 月 7 日 - Apache AntUnit 1.4.1 发布
Apache AntUnit 1.4.1 现在可以作为 二进制 或 源代码 发行版下载。
此版本修复了 antlib.xml 描述符,以便 AntUnit 现在可以使用用户定义的 URI,而不是将 AntUnit 的首选 URI 硬编码。
想法
最初,Apache Ant 任务的所有测试都作为单独的 JUnit 测试用例编写。很快,很明显,大多数测试都需要执行一些常见的任务,例如读取构建文件,用它初始化项目实例并执行目标。此时,BuildFileTest 被发明出来,它是几乎所有任务测试用例的基类。
BuildFileTest 工作正常,事实上,它也被 Ant-Contrib 项目 和其他人采用。
随着时间的推移,一种新的模式出现了,越来越多的测试只执行一个目标,而不检查任何效果。相反,该目标包含断言作为 <fail>
任务。这是一个来自 ANTLR 任务构建文件的示例(使用 Ant 1.7 功能)
<target name="test3" depends="setup"> <antlr target="antlr.g" outputdirectory="${tmp.dir}"/> <fail> <condition> <!-- to prove each of these files exists; ANTLR >= 2.7.6 leaves behind new (.smap) files as well. --> <resourcecount when="ne" count="5"> <fileset dir="${tmp.dir}"> <include name="CalcParserTokenTypes.txt" /> <include name="CalcParserTokenTypes.java" /> <include name="CalcLexer.java" /> <include name="CalcParser.java" /> <include name="CalcTreeWalker.java" /> </fileset> </resourcecount> </condition> </fail> </target>
其中相应的 JUnit 测试用例已简化为
... public class ANTLRTest extends BuildFileTest { private final static String TASKDEFS_DIR = "src/etc/testcases/taskdefs/optional/antlr/"; public ANTLRTest(String name) { super(name); } public void setUp() { configureProject(TASKDEFS_DIR + "antlr.xml"); } public void tearDown() { executeTarget("cleanup"); } public void test3() { executeTarget("test3"); } ... }
这种方法有几个优点,其中之一是将错误报告中的示例构建文件转换为测试用例非常容易。如果你要求用户提供针对 Ant 中给定错误的测试用例,他现在不再需要理解 JUnit 或者如何将测试融入 Ant 的现有测试了。
AntUnit 将这种测试方法更进一步,它完全删除了 JUnit,并提供了一组预定义的 <assert>
任务,以便重用常见的检查类型。
事实证明,AntUnit 也能解决其他问题。断言是一种简单的方法,可以在甚至开始构建过程之前验证设置,例如。AntUnit 也可以用于 Ant 任务范围之外的功能和集成测试(在运行应用程序后断言数据库的内容,断言 HTTP 响应的内容...)。这是一个需要更多研究的领域。
概念
antunit 任务
<antunit>
任务驱动测试,就像 <junit>
对 JUnit 测试一样。
当在构建文件上调用时,该任务将为该构建文件启动一个新的 Ant 项目,并扫描名称以“test”开头的目标。对于每个这样的目标,它将
- 执行名为 setUp 的目标,如果有的话。
- 执行目标本身 - 如果此目标依赖于其他目标,则正常的 Ant 规则适用,并且依赖目标将首先执行。
- 执行名为 tearDown 的目标,如果有的话。
断言
基本任务是 <assertTrue>
。它接受一个嵌套条件,如果该条件计算结果为 false,则抛出一个名为 AssertionFailedException 的 BuildException 子类。
此任务可以使用 <macrodef>
和 <fail>
实现,但实际上它是一个“真实”任务,因此可以抛出 BuildException 的子类。<antunit>
任务捕获此异常并将目标标记为失败,任何其他类型的异常(包括其他 BuildException)都是测试错误。
除了 <assertTrue>
之外,还有许多预定义的断言用于常见条件,其中大多数只是宏。
其他任务
<logcapturer>
捕获所有通过 Ant 日志系统传递的消息,并通过项目中的引用提供它们。如果你想断言某些日志消息,你需要启动此任务(在你的测试目标之前)并使用 <assertLogContains>
断言。
<expectFailure>
是一个任务容器,它捕获嵌套到其中的任务抛出的任何 BuildException。如果没有抛出异常,它将导致测试失败(通过抛出 AssertionFailedException)。
AntUnitListener
库的一部分是 AntUnitListener
接口,它可以用于记录测试结果。<antunit>
任务接受任意多个监听器,并将测试结果转发给它们。
目前,库中捆绑了两个实现 - <plainlistener>
和 xmllistener
,它们模仿“plain”和“xml”JUnit 监听器。
示例
这是一种测试 <touch>
是否真的创建了一个不存在的文件的方法
<project xmlns:au="antlib:org.apache.ant.antunit"> <!-- is called prior to the test --> <target name="setUp"> <property name="foo" value="foo"/> </target> <!-- is called after the test, even if that caused an error --> <target name="tearDown"> <delete file="${foo}" quiet="true"/> </target> <!-- the actual test case --> <target name="testTouchCreatesFile"> <au:assertFileDoesntExist file="${foo}"/> <touch file="${foo}"/> <au:assertFileExists file="${foo}"/> </target> </project>
当从它自己的构建文件运行像
<au:antunit> <fileset dir="." includes="touch.xml"/> <au:plainlistener/> </au:antunit>
这样的任务时,你会得到一个看起来像这样的结果
[au:antunit] Build File: /tmp/touch.xml [au:antunit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.249 sec [au:antunit] Target: testTouchCreatesFile took 0.183 sec BUILD SUCCESSFUL Total time: 1 second