可以用多種方式對 PHPUnit 進行擴展,使編寫測試更容易,以及對運行測試所得到的反饋進行定制。擴展 PHPUnit 時,一般從這些點入手:
將自定義的斷言和工具方法寫在 ?PHPUnit\Framework\TestCase
? 的一個抽象子類中,然后從這個抽象子類派生你的測試用例類。這是擴展 PHPUnit 的最容易的方法。
編寫自定義斷言時,最佳實踐是遵循 PHPUnit 自有斷言的實現(xiàn)方式。正如示例 10.1 中所示,?assertTrue()
? 方法只是對 ?isTrue()
? 和 ?assertThat()
? 方法的封裝:?isTrue()
? 創(chuàng)建了一個匹配器對象,將其傳遞給 ?assertThat()
? 進行評定。
示例 10.1 PHPUnit\Framework\Assert 類的 assertTrue() 和 isTrue() 方法
<?php declare(strict_types=1);
namespace PHPUnit\Framework;
use PHPUnit\Framework\Constraint\IsTrue;
abstract class Assert
{
// ...
public static function assertTrue($condition, string $message = ''): void
{
static::assertThat($condition, static::isTrue(), $message);
}
// ...
public static function isTrue(): IsTrue
{
return new IsTrue;
}
// ...
}
示例 10.2 展示了 ?PHPUnit\Framework\Constraint\IsTrue
? 是如何擴展針對匹配器對象(或約束)的抽象基類 ?PHPUnit\Framework\Constraint
? 的。
示例 10.2 PHPUnit\FrameworkConstraint\IsTrue 類
<?php declare(strict_types=1);
namespace PHPUnit\Framework\Constraint;
use PHPUnit\Framework\Constraint;
final class IsTrue extends Constraint
{
public function toString(): string
{
return 'is true';
}
protected function matches($other): bool
{
return $other === true;
}
}
在實現(xiàn) ?assertTrue()
? 和 ?isTrue()
? 方法及 ?PHPUnit\Framework\Constraint\IsTrue
? 類時所付出的努力帶來了一些好處,?assertThat()
? 能夠自動負責起斷言的評定與任務簿記(例如為了統(tǒng)計目的而對其進行計數(shù))工作。此外, ?isTrue()
? 方法還可以在配置仿件對象時用來作為匹配器。
PHPUnit 的測試執(zhí)行器可以通過注冊實現(xiàn)了一個或多個以下接口的對象來進行擴展:
AfterIncompleteTestHook
?AfterLastTestHook
?AfterRiskyTestHook
?AfterSkippedTestHook
?AfterSuccessfulTestHook
?AfterTestErrorHook
?AfterTestFailureHook
?AfterTestWarningHook
?AfterTestHook
?BeforeFirstTestHook
?BeforeTestHook
?每個“hook”(表示上面列出的各個接口)都代表一個可能在測試執(zhí)行過程中發(fā)生的事件。
示例 10.3 展示了一個實現(xiàn)了 ?BeforeFirstTestHook
? 和 ?AfterLastTestHook
?的擴展:
示例 10.3 測試執(zhí)行器擴展示例
<?php declare(strict_types=1);
namespace Vendor;
use PHPUnit\Runner\BeforeFirstTestHook;
use PHPUnit\Runner\AfterLastTestHook;
final class MyExtension implements BeforeFirstTestHook, AfterLastTestHook
{
public function executeBeforeFirstTest(): void
{
// 運行第一個測試之前調(diào)用
}
public function executeAfterLastTest(): void
{
// 運行完最后一個測試之后調(diào)用
}
}
假定擴展接受配置值,則你可以對 PHPUnit 擴展進行配置。
示例 10.4 展示了如何通過為擴展類添加 ?__constructor()
? 定義讓擴展可配置:
示例 10.4 帶有構造函數(shù)的測試執(zhí)行器擴展
<?php declare(strict_types=1);
namespace Vendor;
use PHPUnit\Runner\BeforeFirstTestHook;
use PHPUnit\Runner\AfterLastTestHook;
final class MyConfigurableExtension implements BeforeFirstTestHook, AfterLastTestHook
{
protected $config_value_1 = '';
protected $config_value_2 = 0;
public function __construct(string $value1 = '', int $value2 = 0)
{
$this->config_value_1 = $config_1;
$this->config_value_2 = $config_2;
}
public function executeBeforeFirstTest(): void
{
if (strlen($this->config_value_1) {
echo 'Testing with configuration value: ' . $this->config_value_1;
}
}
public function executeAfterLastTest(): void
{
if ($this->config_value_2 > 10) {
echo 'Second config value is OK!';
}
}
}
要通過 XML 給擴展輸入配置,必須更新 XML 配置文件的 ?extensions
段來讓其擁有配置值,如示例 10.5 中所示:
示例 10.5 測試執(zhí)行器擴展配置
<extensions>
<extension class="Vendor\MyUnconfigurableExtension" />
<extension class="Vendor\MyConfigurableExtension">
<arguments>
<string>Hello world!</string>
<int>15</int>
</arguments>
</extension>
</extensions>
請記?。核信渲枚际强蛇x的,因此要確保你的配置要么要有健全的默認值,要么它就應當在缺失配置的時候禁用自身。
更多建議: