Closed hgsgtk closed 5 years ago
xUnit Test Patterns
Test Discovery vs Test Enumeration 自分で意図的に登録していくのが後者、多くのxUnitファミリーはTest Discoveryを実装している
Test Selection - to run subsets of test methods based on some criteria Test Suiteとは微妙に趣向が違うらしい https://stackoverflow.com/questions/16707680/junit-test-methods-selection-at-runtime
テスティングフレームワーク自作といえばうさみさん
dataProvider系のことをしようとしたらPHPDoc
Specify a test as a Test Method (page 348)
Test Methodを認識して実行する
test
という接頭辞ではじまる関数
- @internal This class is not covered by the backward compatibility promise for PHPUnit 後方互換?
Test Interfaceはrun()
というメソッドを持っている
/**
* A Test can be run and collect its results.
*/
interface Test extends Countable
{
/**
* Runs a test and collects its result in a TestResult instance.
*/
public function run(TestResult $result = null): TestResult;
}
このインターフェースを実装していることがテスト実行・結果の収集の条件
このインタフェースが継承しているのが、Countable Interface
interface Countable {
/**
* Count elements of an object
* @link https://php.net/manual/en/countable.count.php
* @return int The custom count as an integer.
* </p>
* <p>
* The return value is cast to an integer.
* @since 5.1.0
*/
public function count();
}
このインターフェースを実装していると、count()
で結果が返ってくる
また、このTest
インターフェースは、TestResultを引数に持ち・戻り値として返す
このTestResultクラスは、テスト結果を持っている。
/**
* @var array
*/
private $passed = [];
/**
* @var TestFailure[]
*/
private $errors = [];
/**
* @var TestFailure[]
*/
private $failures = [];
これらの結果に追加するメソッドとしてaddError
やaddWarning
などが存在している
また、ゲッターとして、次のようなpublicインターフェースが用意されている
public function failures(): array
{
return $this->failures;
}
さらに、実際にテストケースを実行するrun()
も存在
かなり長いこれまでのpublicメソッドはほとんど使われている。別のインターフェースがTestResultに混じっているようなそんなクラスになっている印象
AssertにはassertXxx
の機能がstaticメソッドで実装されている。継承関係なんだろうか、traitとかの類なきがするのはおれだけか?
IsEmpty
などそれぞれ別クラスで定義してる
matches
でboolで結果を返せる
failureDescription
で失敗時の説明を文字列で渡している
ただし、外側から使われているのは、継承元の親クラスConstraint::evaluate()
。このメソッドの中でmatches
が呼ばれる、形式的にはテンプレートメソッドパターンに近い方法。
Constraint
クラスではこのmatches
は、例外などはでないがfalse
が定型的に変えるよというものになっている。
composer.jsonでは、トップディレクトリのphpunit
を示している
"bin": [
"phpunit"
],
このbinでは、TextUI/Command::main()
を実行する
mainは、コマンド引数とともに自身のrun()
を実行
コマンド引数をまず解釈する
ここでTestRunner
クラスを生成する、
このTestRunner
は必要なテストを集めてきて(getTest()
)、それらを実行する(doRun()
)
addXXXというメソッドがTestResultというクラスに存在してる。シグネチャは次の通り
public function addError(Test $test, Throwable $t, float $time): void
この第一引数のTest
クラスではCountableインターフェースを実装しており、つまり、count()でカウントできるものになっている。(アサーションの数をカウントできるようになっている?)
この処理の中では、IncompleteTestやSkippedTestといったinstanceかどうかを確認しており、その確認結果に基づいてような処理を変更している。
TestFailureクラスだった場合は、TestResult->errorの配列にTestInterfaceを実装したクラスが追加されていく。 (クラスにしよ)
Test Interfaceは次の通り
interface Test extends Countable
{
/**
* Runs a test and collects its result in a TestResult instance.
*/
public function run(TestResult $result = null): TestResult;
}
Testはrun()だけもっていればいい。TestResultを渡して結果を記録してまたTestResultを返す。ふーん。
初期開発における開発ロードマップを検討する