🙄

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

2022/11/19に公開

はじめに

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

環境

  • PHP 8.2.3
  • PHPUnit 10.0.13

調べる対象のメソッド

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

確認用ソースコード

<?php

declare(strict_types=1);

namespace Tests;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Throwable;

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): never
    {
        fwrite(STDOUT, __METHOD__ . PHP_EOL);
        throw $t;
    }

    public static 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')]
    public function testMethod3(int $a): void
    {
        fwrite(STDOUT, __METHOD__ . PHP_EOL);
        $this->assertTrue(true);
    }
}

結果

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

Runtime:       PHP 8.2.3
Configuration: /var/www/html/phpunit.xml

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.025, Memory: 10.00 MB

There was 1 failure:

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

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

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