web-dev-qa-db-ja.com

PHPUnit:すべてのテストで1回呼び出される関数を作成するにはどうすればよいですか?

PHPUnitテストケースクラスがあります(いくつかのテスト関数で構成されています)。クラス内のすべてのテストで1回呼び出されるoneTimeSetUp()関数を作成します(クラス内の各テストで1回呼び出される標準のsetUp()関数とは異なります)。つまり、 JUnit _@BeforeClass_アノテーション に相当するPHPUnitを探しています。

oneTimeTearDown()関数に関する同じ質問。

PHPUnitでこれを行うことはできますか?

57
snakile

PHPUnitドキュメントの section 6 からsetUpBeforeClass()を見てください。

一度だけtearDownするには、tearDownAfterClass();を使用する必要があります。

このメソッドは両方とも、静的メソッドとしてクラスで定義する必要があります。

87
borrible

私は同じ質問でこのページに来ましたが、受け入れられた答えはすべてのクラスで実行され、私にとっては正しい答えではありませんでした。

あなたが私のような場合、最初の「統合テスト」は、DBをクリアし、移行を実行することです。これにより、すべてのテストのデータベースベースラインに到達します。この時点で移行ファイルは常に変更されているため、ベースラインの設定はすべてのテストの一部です。

移行には時間がかかるため、すべてのテストで実行することは望ましくありません。

次に、各ピースをテストするデータベースを構築する必要がありました。注文テストを作成する必要がありますが、最初にいくつかの製品を作成してテストする必要があり、次に輸入機能をテストする必要があります。

ですから、私がしたことはとても簡単ですが、インターネット上ではあまり説明されていません。データベースをセットアップする簡単なテストを作成しました。次に、phpspec.xmlファイルにテストスイートを追加します...

<testsuite name="Products">
    <file>tests/in/SystemSetupTest.php</file>
    <file>tests/in/ProductTest.php</file>
    <file>tests/in/ProductImportTest.php</file>
</testsuite>

そして、SystemSetupTest.phpで....

class SystemSetupTest extends ApiTester
{

    /** @test */
    function system_init()
    {
        fwrite(STDOUT, __METHOD__ . "\n");
        self::createEM(); //this has all the code to init the system...
    }
}

次に、次のように実行します。

phpunit --testsuite製品

結局、そのトンは簡単です。システムを正しく構築することができます。

さらに、laravel 5を使用しています。setUpBeforeClass()を使用すると、bootstrapの問題が発生します。これは修正できるはずですが、上記で使用した方法は完璧です。 。

7
Iannazzi

setUpBeforeClass()は、すべてのテストが文字通り単一のクラスに含まれている場合にこれを行う方法です。

ただし、質問の種類は、テストクラスを複数のテストクラスの基本クラスとして使用している可能性があることを意味します。その場合、それぞれの前にsetUpBeforeClassが実行されます。一度だけ実行したい場合は、静的変数でガードできます:

abstract class TestBase extends TestCase {

  protected static $initialized = FALSE;

  public function setUp() {
    if (!self::$initialized) {
      // Do something once here for _all_ test subclasses.
      self::$initialized = TRUE;
    }
  }

}

最後のオプションは テストリスナー です。

4
Dane Powell

bootstrapオプションは、これらの場合に使用できます。

コマンドラインから呼び出すことができます

phpunit --bootstrap myBootstrap.php

または、次のようにXMLファイルに配置します。

<phpunit bootstrap="myBootstrap.php">
...
</phpunit>
1
Gustavo Alves

受け入れられた答えを拡張する:

setUpBeforeClass()tearDownAfterClass()@beforeClass@afterClassはいずれもオブジェクトコンテキストで実行されません(静的メソッド)。代わりに、静的プロパティで@beforeコードを保護することで、この制限を回避できます。

class MyTest extends PHPUnit\Framework\TestCase
{
    private static $ready;

    /**
     * @before
     */
    protected function firstSetUp()
    {
        if (self::$ready))
            return;

        /* your one time setUp here */

        self::$ready = true;
    }
}

ただし、@afterには使用できません。最後のテストがいつ呼び出されたかを伝える方法がないためです。

0
cprn