🙄

PHPUnitのテストクラスのメソッドの動く順番を調べた

2022/11/19に公開約3,800字

はじめに

以前、PHPUnitのsetUptearDownなどがどのタイミングで動くのか調べていたので、
結果を書いておこうと思います。

環境

  • PHP 8.1.9
  • PHPUnit 9.5.26

調べる前に...

公式マニュアルをみると...すでに書いてありました。
https://phpunit.readthedocs.io/ja/latest/fixtures.html
Example 4.2 利用可能なすべてのテンプレートメソッドを参照

なので、今回はマニュアルに載っていない、データプロバイダを追加してしらべてみたいと思います。

調べる対象のメソッド

  • setUp
  • tearDown
  • setUpBeforeClass
  • tearDownAfterClass
  • assertPreConditions
  • assertPostConditions
  • onNotSuccessfulTest
  • データプロバイダ

確認用ソースコード

<?php

declare(strict_types=1);

namespace Tests;

use PHPUnit\Framework\TestCase;

class LifecycleTest extends TestCase
{
    public static function setUpBeforeClass(): void
    {
        fwrite(STDOUT, __METHOD__ . PHP_EOL);
    }

    public static function tearDownAfterClass(): void
    {
        fwrite(STDOUT, PHP_EOL . __METHOD__ . PHP_EOL);
    }

    protected function setUp(): void
    {
        fwrite(STDOUT, PHP_EOL . __METHOD__ . PHP_EOL);
    }

    protected function tearDown(): void
    {
        fwrite(STDOUT, __METHOD__ . PHP_EOL);
    }

    protected function assertPreConditions(): void
    {
        fwrite(STDOUT, __METHOD__ . PHP_EOL);
    }

    protected function assertPostConditions(): void
    {
        fwrite(STDOUT, __METHOD__ . PHP_EOL);
    }

    protected function onNotSuccessfulTest(\Throwable $t): void
    {
        fwrite(STDOUT, __METHOD__ . PHP_EOL);
        throw $t;
    }

    public function dataProvider(): array
    {
        fwrite(STDOUT, __METHOD__ . PHP_EOL);
        return [
            [1],
            [2],
            [3],
        ];
    }

    public function testMethod1(): void
    {
        fwrite(STDOUT, __METHOD__ . PHP_EOL);
        $this->assertTrue(true);
    }

    public function testMethod2(): void
    {
        fwrite(STDOUT, __METHOD__ . PHP_EOL);
        $this->assertTrue(false);
    }

    /**
     * @dataProvider dataProvider
     *
     * @param int $a
     */
    public function testMethod3(int $a): void
    {
        fwrite(STDOUT, __METHOD__ . PHP_EOL);
        $this->assertTrue(true);
    }
}

結果

$ vendor/bin/phpunit tests/LifecycleTest.php 
Tests\LifecycleTest::dataProvider
PHPUnit 9.5.26 by Sebastian Bergmann and contributors.

Tests\LifecycleTest::setUpBeforeClass

Tests\LifecycleTest::setUp
Tests\LifecycleTest::assertPreConditions
Tests\LifecycleTest::testMethod1
Tests\LifecycleTest::assertPostConditions
Tests\LifecycleTest::tearDown
.
Tests\LifecycleTest::setUp
Tests\LifecycleTest::assertPreConditions
Tests\LifecycleTest::testMethod2
Tests\LifecycleTest::tearDown
Tests\LifecycleTest::onNotSuccessfulTest
F
Tests\LifecycleTest::setUp
Tests\LifecycleTest::assertPreConditions
Tests\LifecycleTest::testMethod3
Tests\LifecycleTest::assertPostConditions
Tests\LifecycleTest::tearDown
.
Tests\LifecycleTest::setUp
Tests\LifecycleTest::assertPreConditions
Tests\LifecycleTest::testMethod3
Tests\LifecycleTest::assertPostConditions
Tests\LifecycleTest::tearDown
.
Tests\LifecycleTest::setUp
Tests\LifecycleTest::assertPreConditions
Tests\LifecycleTest::testMethod3
Tests\LifecycleTest::assertPostConditions
Tests\LifecycleTest::tearDown
.                                                               5 / 5 (100%)
Tests\LifecycleTest::tearDownAfterClass


Time: 00:00.083, Memory: 8.00 MB

There was 1 failure:

1) Tests\LifecycleTest::testMethod2
Failed asserting that false is true.

/var/www/html/tests/LifecycleTest.php:66

FAILURES!
Tests: 5, Assertions: 5, Failures: 1.

まとめ

次のような結果になりました。

  1. データプロバイダ
    ・最初に1回だけ動く
  2. setUpBeforeClass
    ・最初に1回だけ動く
  3. setUp
    ・各テストメソッドの実行前に動く
  4. assertPreConditions
    ・各テストメソッドの実行前に動く
  5. テストメソッド
  6. assertPostConditions
    ・各テストメソッドの実行後に動く
    ・テストが成功した場合のみ動く
  7. tearDown
    ・各テストメソッドの実行後に動く
  8. onNotSuccessfulTest
    ・各テストメソッドの実行後に動く
    ・テストが失敗した場合のみ動く
  9. tearDownAfterClass
    ・最後に1回だけ動く

マニュアルには載っていないデータプロバイダが1番最初に動くことが判明
あとは、マニュアルの通りの結果ですね

Discussion

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