この記事では xUnit (PHPUnit や JUnit など)を使った自動テストを作成する上での秘訣をご紹介します。
今回ご紹介する秘訣は「テストメソッドの独立」についてです。
独立していないテスト
サンプルとして、以下のようなメールアドレスを登録する機能について考えてみましょう。
-
register()
メソッドで、メールアドレスをDBに登録する。 - 登録時、アドレスが登録済みのものと重複している場合はエラーメッセージを返す。
これをテストするコードは、例えば以下のようになります。(PHP で書かれています。)
public class SampleTest extends TestCase
{
/** テスト対象 */
private $testing;
public static function setUpBeforeClass(): void
{
// ... DB を初期化する
}
public function setUp(): void
{
$this->testing = ... ; // テスト対象を生成する
}
/** 登録が成功することを検証する。 */
public function testRegister(): void
{
$result = $this->testing->register('my-email@example.com');
$this->assertSame(200, $result->getStatus());
$this->assertSame('成功!', $result->getMessage());
}
/** メールアドレスが重複している場合はエラー */
public function testEmailDuplicated(): void
{
$result = $this->testing->register('my-email@example.com');
$this->assertSame(400, $result->getStatus(), '重複したメールの登録は失敗するべき。');
$this->assertSame('メールアドレスが重複しています。', $result->getMessage());
}
}
testRegister()
で登録したメールアドレスを testEmailDuplicated()
で再度登録し、重複エラーが発生するケースを検証しています。
一見して問題ないように見えますが、このテストは1つ大きな問題が存在します。以下のように testEmailDuplicated()
だけを実行すると、テストが失敗するのです。
phpunit --filter SampleTest::testEmailDuplicated
先ほどの例ではテストメソッドが2つだけですが、さらにテストメソッドが増えた場合はどうなるでしょうか? テストAがテストBに依存していて、そのテストBがテストCやDに依存していたとしたら……?
このように、テストメソッド同士が依存するとそれを修正するのが大変になり、余計な時間がかかるのです。
そうならないためには、各テストメソッドを独立させる必要があります。
独立したテスト
先ほどのテストを書き直したものが、以下になります。
/** 登録が成功することを検証する。 */
public function testRegister(): void
{
$result = $this->testing->register('my-email@example.com');
$this->assertSame(200, $result->getStatus());
$this->assertSame('成功!', $result->getMessage());
}
/** メールアドレスが重複している場合はエラー */
public function testEmailDuplicated(): void
{
$this->testing->register('test-duplicated@example.com');
$this->assertSame(200, $result->getStatus(), '1度目の登録は成功するべき。');
$result = $this->testing->register('test-duplicated@example.com');
$this->assertSame(400, $result->getStatus(), '2度目の登録は失敗するべき。');
$this->assertSame('メールアドレスが重複しています。', $result->getMessage());
}
先ほどの例とは違い、 testEmailDuplicated()
のみでテストを実行しても成功します。
このように独立したテストを書くことで、テストが複雑化するのを防ぎ、その後の修正が容易になるのです。
ちなみに、独立したテストメソッドとは以下のようなものです。
- テストメソッドを単体で実行しても正しく動作する。
- テストメソッドの実行順を変えても正しく動作する。
まとめ
各テストメソッドを独立させることで、その後のテスト修正が容易になり、時間の節約になります。
他のテストで作られたデータや結果に依存しないよう、注意してテストを作りましょう!