LoginSignup
0
1

自動テストの秘訣: テストメソッドを独立させる

Last updated at Posted at 2024-06-24

この記事では 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() のみでテストを実行しても成功します。

このように独立したテストを書くことで、テストが複雑化するのを防ぎ、その後の修正が容易になるのです。

ちなみに、独立したテストメソッドとは以下のようなものです。

  • テストメソッドを単体で実行しても正しく動作する。
  • テストメソッドの実行順を変えても正しく動作する。

まとめ

各テストメソッドを独立させることで、その後のテスト修正が容易になり、時間の節約になります。

他のテストで作られたデータや結果に依存しないよう、注意してテストを作りましょう!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1