📝

PHPUnitの@testWithアノテーションの文字列はダブルクオーテーションで指定する

2023/01/05に公開約2,100字

みんな大好きPHPUnitのテストで使える@testWithアノテーション。
今までdataProviderしか使っていなかったんですが、メソッドのDocコメント部分にかけてテスト内容と検証したい要素がすぐ近くに掛けて便利なので使用することにしたんですが、文字列の扱いでどハマりしてしまったので備忘録を残しておきます。

@testWith

@testWithはDoc欄に記載することでテストに使いたいデータを羅列する事ができます。

使い方はこんな感じ。

/**
 * Taxクラスに対するテストコード。
 * Taxクラスは受け取った数値に1.1を掛けて返すだけの単純なクラスを想定。
 * calc_taxメソッドが実装されていて、このcalc_taxメソッドに対するテスト。
 */

<?php
declare( strict_types = 1 );

class TaxTest extends PHPUnit\Framework\TestCase {
	/**
	 * @var object $instance instance.
	 */
	private $instance;

	/**
	 * SetUp.
	 * Create instance.
	 */
	protected function setUp() :void {
		$this->instance = new Tax();
	}
    
	/**
	 * @testWith [ 100, 110 ]
	 *           [ 500, 550 ]
	 *           [ 1000, 1100 ]
	 */
	public function test_calc_tax( $price, $tax_included ) {
	    $this->assertSame(
	        $this->assertSame( $tax_included, $this->instance->calc_tax( $price ) )
	    );
	}
}

dataProviderを使う場合、テストが多くなればテストとdataProviderが別々の場所に書くことになってしまいどんなデータをテストしているのか分かりにくくなります。
その点@testWithアノテーションの場合テストの真上にDocとして書けるので非常に便利。

文字列はダブルクオーテーションを使う

で、上記のテストの場合は数値(int)なので全く問題無いんですが、値が文字列の場合注意が必要です。

先述したコード、普通ありえませんが文字列で数字を渡して計算結果を文字列で受け取る場合を想定して次のようなアノテーションを書きました。

/**
 * @testWith [ '100', '110' ]
 *           [ '500', '550' ]
 *           [ '1000', '1100' ]
 */

普段文字列はシングルクオーテーション派だったのでいつも通り記述しましたが、何度やってもテストが通りません。
テストに失敗する、ではなくsyntax errorと指摘される始末。
構文エラーということは公式を見るのが一番なので早速見に行ってみました。

データセットには複数の要素を含めることができます。 複数の要素からなるデータセットを定義するには、要素ごとに別の行で定義します。 データセットの要素は、JSONの配列形式でなければいけません。 2. アノテーション — PHPUnit latest Manualより引用

ということで正しいJSON形式じゃないからエラーになったということのようです。
(JSONはKey/Valueの指定をダブルクオーテーションで行う、シングルクオーテーションはNG)

つまり以下のように書けばOK。

/**
 * @testWith [ "100", "110" ]
 *           [ "500", "550" ]
 *           [ "1000", "1100" ]
 */

ぶっちゃけその辺はPHPのお作法に従ってシングルクオーテーションで書けるようにしてくれよん・・・と思わないでもないですが、無事テストが通りました。

困ったら公式

実は公式を見る前になんやかんや試行錯誤して20分近くどハマりしました、やっぱりまず公式を見るのを意識するべきですね。
案外使い慣れているフレームワークやパッケージも、たまに公式ドキュメントを見ると新たな発見があったりするので2023年は今まで以上に公式参りをする年にしたいと思います。
皆さん2023年もよろしくお願い致します!

GitHubで編集を提案

Discussion

ログインするとコメントできます