プロジェクトのPHPUnitが古く、バージョンを上げようと思った。
最近の変更点を見ていたらtestWith
アノテーションというのが4.8から増えたことに気づく。
便利そうなので使おうと思ったががパッと見でドキュメントが見当たらなかったのでメモを残す。
(2018/07/31追記)
いつのまにかドキュメントが増えていた。
2. アノテーション@testWith
環境
Installing phpunit/phpunit (5.7.8)
PHP 7.1.0 (cli) (built: Jan 3 2017 15:32:50) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.1.0-dev, Copyright (c) 1998-2016 Zend Technologies
with Zend OPcache v7.1.0, Copyright (c) 1999-2016, by Zend Technologies
with Xdebug v2.5.0, Copyright (c) 2002-2016, by Derick Rethans
結論
json形式で指定しましょう。
連想配列だけちょっと特殊だから気をつける。
とりあえず使ってみる
数値
/**
* @testWith [1, 2, 3]
* [1.1, 2.2, 3.3]
*/
public function testNum($a, $b, $expected)
{
$this->assertEquals($expected, $a + $b);
}
文字列
/**
* @testWith ["a", "b", "ab"]
*/
public function testStr($a, $b, $expected)
{
$this->assertEquals($expected, $a . $b);
}
配列
/**
* @testWith [["a"], ["b"], ["a","b"]]
*/
public function testAry($a, $b, $expected)
{
$this->assertEquals($expected, array_merge($a, $b));
}
ここまでは想定内。
連想配列
/**
* @testWith [["a"=>1], ["b"=>2], ["a"=>1,"b"=>2]]
*/
public function testHash($a, $b, $expected)
{
$this->assertEquals($expected, array_merge($a, $b));
}
配列までのノリで出来るかと思ったらテスト始まらなかったので指定の仕方おかしいんだろうということでソースを確認。
if (preg_match(self::REGEX_TEST_WITH, $docComment, $matches, PREG_OFFSET_CAPTURE)) {
$offset = strlen($matches[0][0]) + $matches[0][1];
$annotationContent = substr($docComment, $offset);
$data = [];
foreach (explode("\n", $annotationContent) as $candidateRow) {
$candidateRow = trim($candidateRow);
if ($candidateRow[0] !== '[') {
break;
}
$dataSet = json_decode($candidateRow, true);
if (json_last_error() != JSON_ERROR_NONE) {
throw new PHPUnit_Framework_Exception(
'The dataset for the @testWith annotation cannot be parsed: ' . json_last_error_msg()
);
}
$data[] = $dataSet;
}
if (!$data) {
throw new PHPUnit_Framework_Exception('The dataset for the @testWith annotation cannot be parsed.');
}
return $data;
}
引用元:
https://github.com/sebastianbergmann/phpunit/blob/5.7/src/Util/Test.php#L511
うん、めっちゃjson_decode
している。
よって連想配列を指定したい場合は下記のようになる。
/**
* @testWith [{"a": 1}, {"b": 2}, {"a": 1, "b": 2}]
*/
public function testHash($a, $b, $expected)
{
$this->assertEquals($expected, array_merge($a, $b));
}
まとめ
一通り指定は出来るのでよっぽど無い限り簡単なテストはtestWithアノテーションでいいのかなと思ったり。
色々やりたいぞいってなったら普段どおりdataProviderアノテーションで頑張る感じで!
参考
PHPUnit の各バージョンについて調べてみた
Annotation @testWith not documented
2018/03/13 ドキュメントが追加されてることに気付いたが連想配列周りの罠に関しては未記載っぽい
2. アノテーション@testWith