PHPUnit 的目标之一是测试应当可组合:我们希望能将任意数量的测试以任意组合方式运行,例如,整个项目的所有测试,或者项目中的某个组件内的所有类的测试,又或者仅仅某单个类的测试。
PHPUnit 支持好几种不同的方式来组织测试以及将它们编排组合成测试套件。本章介绍了最常用的方法。
编排测试套件的各种方式中,最简单的大概就是把所有测试用例源文件放在一个测试目录中。通过对测试目录进行递归遍历,PHPUnit 能自动发现并运行测试。
让我们一起来看看 Object_Freezer 这个库的测试套件。在这个项目的目录结构中,可以看到 Tests
目录下的测试用例类镜像了 Object
目录下被测系统(SUT, System Under Test)的包(package)与类(class)的结构:
Object Tests |-- Freezer |-- Freezer | |-- HashGenerator | |-- HashGenerator | | `-- NonRecursiveSHA1.php | | `-- NonRecursiveSHA1Test.php | |-- HashGenerator.php | | | |-- IdGenerator | |-- IdGenerator | | `-- UUID.php | | `-- UUIDTest.php | |-- IdGenerator.php | | | |-- LazyProxy.php | | | |-- Storage | |-- Storage | | `-- CouchDB.php | | `-- CouchDB | | | | |-- WithLazyLoadTest.php | | | | `-- WithoutLazyLoadTest.php | |-- Storage.php | |-- StorageTest.php | `-- Util.php | `-- UtilTest.php `-- Freezer.php `-- FreezerTest.php
要运行这个库的全部测试,只要将 PHPUnit 命令行测试执行器指向测试目录即可:
phpunit Tests
PHPUnit 4.2.0 by Sebastian Bergmann.
............................................................ 60 / 75
...............
Time: 0 seconds
OK (75 tests, 164 assertions)
当 PHPUnit 命令行测试执行器指向一个目录时,它会在目录下查找 *Test.php
文件。
如果只想运行在 Tests/FreezerTest.php
文件中的 Object_FreezerTest
测试用例类中声明的测试,可以使用如下命令:
phpunit Tests/FreezerTest
PHPUnit 4.2.0 by Sebastian Bergmann.
............................
Time: 0 seconds
OK (28 tests, 60 assertions)
如果想要对运行哪些测试有更细粒度的控制,可以使用 --filter
选项:
phpunit --filter testFreezingAnObjectWorks Tests
PHPUnit 4.2.0 by Sebastian Bergmann.
.
Time: 0 seconds
OK (1 test, 2 assertions)
这种方法的缺点是无法控制测试的运行顺序。这可能导致测试的依赖关系方面的问题,参见“测试的依赖关系”一节。在下一节中,可以看到如何用 XML 配置文件来明确指定测试的执行顺序。
PHPUnit的 XML 配置文件(附录 C)也可以用于编排测试套件。例 5.1展示了一个最小化的例子,它将在循环遍历 Tests
时添加所有在 *Test.php
文件中找到的 *Test
类。
例 5.1: 用 XML 配置来编排测试套件
<phpunit> <testsuites> <testsuite name="Object_Freezer"> <directory>Tests</directory> </testsuite> </testsuites> </phpunit>
可以明确指定测试的执行顺序:
例 5.2: 用 XML 配置来编排测试套件
<phpunit> <testsuites> <testsuite name="Object_Freezer"> <file>Tests/Freezer/HashGenerator/NonRecursiveSHA1Test.php</file> <file>Tests/Freezer/IdGenerator/UUIDTest.php</file> <file>Tests/Freezer/UtilTest.php</file> <file>Tests/FreezerTest.php</file> <file>Tests/Freezer/StorageTest.php</file> <file>Tests/Freezer/Storage/CouchDB/WithLazyLoadTest.php</file> <file>Tests/Freezer/Storage/CouchDB/WithoutLazyLoadTest.php</file> </testsuite> </testsuites> </phpunit>