Incomplete and Skipped Tests

Incomplete and Skipped Tests

不完整的测试

当您正在处理新的测试用例类时,您可能需要先编写空的测试方法,例如:

public function testSomething() { }

跟踪您必须编写的测试。空测试方法的问题在于它们被 PHPUnit 框架解释为成功。这种误解会导致测试报告无用 - 您无法看到测试是否成功或尚未实施。调用$this->fail()未实现的测试方法也无济于事,因为此后测试将被解释为失败。这与将未执行的测试解释为成功一样是错误的。

If we think of a successful test as a green light and a test failure as a red light, we need an additional yellow light to mark a test as being incomplete or not yet implemented. `PHPUnit_Framework_IncompleteTest` is a marker interface for marking an exception that is raised by a test method as the result of the test being incomplete or currently not implemented. `PHPUnit_Framework_IncompleteTestError` is the standard implementation of this interface.

例7.1显示了一个测试用例类SampleTest,它包含一个测试方法,testSomething()。通过在测试方法中调用便利方法markTestIncomplete()(会自动引发PHPUnit_Framework_IncompleteTestError异常),我们将测试标记为不完整。

例7.1:将测试标记为不完整

<?php use PHPUnit\Framework\TestCase; class SampleTest extends TestCase { public function testSomething() { // Optional: Test anything here, if you want. $this->assertTrue(true, 'This should already work.' // Stop here and mark this test as incomplete. $this->markTestIncomplete( 'This test has not been implemented yet.' } } ?>

一个不完整的测试用I PHPUnit 命令行测试运行器的输出中的一个表示,如以下示例所示:

phpunit --verbose SampleTest PHPUnit 6.4.0 by Sebastian Bergmann and contributors. I Time: 0 seconds, Memory: 3.95Mb There was 1 incomplete test: 1) SampleTest::testSomething This test has not been implemented yet. /home/sb/SampleTest.php:12 OK, but incomplete or skipped tests! Tests: 1, Assertions: 1, Incomplete: 1.

表7.1显示了将测试标记为不完整的 API 。

表7.1.不完整测试的 API

MethodMeaning
void markTestIncomplete()Marks the current test as incomplete.
void markTestIncomplete(string $message)Marks the current test as incomplete using $message as an explanatory message.

跳过测试

并非所有测试都可以在每个环境中运行。举个例子,考虑一个数据库抽象层,它为它所支持的不同数据库系统提供了多个驱动程序。MySQL 驱动程序的测试当然只能在 MySQL 服务器可用的情况下运行。

例7.2显示了一个测试用例类DatabaseTest,它包含一个测试方法,testConnection()。在测试用例类的setUp()模板方法中,我们检查 MySQLi 扩展是否可用,markTestSkipped()如果不是,则使用该方法跳过测试。

例7.2:跳过一个测试

<?php use PHPUnit\Framework\TestCase; class DatabaseTest extends TestCase { protected function setUp() { if (!extension_loaded('mysqli')) { $this->markTestSkipped( 'The MySQLi extension is not available.' } } public function testConnection() { // ... } } ?>

S在 PHPUnit 命令行测试运行器的输出中用一个已跳过的测试表示,如以下示例所示:

phpunit --verbose DatabaseTest PHPUnit 6.4.0 by Sebastian Bergmann and contributors. S Time: 0 seconds, Memory: 3.95Mb There was 1 skipped test: 1) DatabaseTest::testConnection The MySQLi extension is not available. /home/sb/DatabaseTest.php:9 OK, but incomplete or skipped tests! Tests: 1, Assertions: 0, Skipped: 1.

表7.2显示了用于跳过测试的 API 。

表7.2.用于跳过测试的 API

MethodMeaning
void markTestSkipped()Marks the current test as skipped.
void markTestSkipped(string $message)Marks the current test as skipped using $message as an explanatory message.

使用 @requires 跳过测试

除了上述方法之外,还可以使用@requires注释来表示测试用例的常见先决条件。

表7.3.可能 @requires 用法

TypePossible ValuesExamplesAnother example
PHPAny PHP version identifier@requires PHP 5.3.3@requires PHP 7.1-dev
PHPUnitAny PHPUnit version identifier@requires PHPUnit 3.6.3@requires PHPUnit 4.6
OSA regexp matching PHP_OS@requires OS Linux@requires OS WIN32|WINNT
functionAny valid parameter to function_exists@requires function imap_open@requires function ReflectionMethod::setAccessible
extensionAny extension name along with an optional version identifier@requires extension mysqli@requires extension redis 2.2.0

例7.3:使用 @requires 跳过测试用例

<?php use PHPUnit\Framework\TestCase; /** * @requires extension mysqli */ class DatabaseTest extends TestCase { /** * @requires PHP 5.3 */ public function testConnection() { // Test requires the mysqli extension and PHP >= 5.3 } // ... All other tests require the mysqli extension } ?>

如果您使用的语法不是使用特定的 PHP 版本进行编译,请查看名为“测试套件”的部分,查看版本相关的 xml 配置,