12

興味深い問題に直面しています。私は PHPUnit を使用していますが、テストを実行するたびにより多くのメモリを消費します。つまり...

2.25MB

2.5MB

3.0MB

3.5メガバイト.......

消費されているメモリをクリアする方法を知っている人はいますか? 当面の問題は、大規模なテストの一部でメモリが不足していることです。PHP の最大メモリ割り当てを増やし続けるだけでは十分ではありません...コマンド ラインから実行する PHPUnit テストでメモリが不足する理由を知る必要があります。実行間で「固執する」使用法。

4

4 に答える 4

26

メモリの増加には、3〜4つの理由があります。

1)PHPUnitはコードカバレッジデータを収集します

コードカバレッジをオフにする以外に、これについてできることは何もありません。

2)PHPUnitは、コードカバレッジのためにファイルトークンをキャッシュします

<phpunit cacheTokens="false">PHPUnitxmlで使用できます。http://phpunit.de/manual/current/en/installation.html#installing.upgradingでこれに関するメモを参照してください

3)PHPUnitはそれ自体の後で適切にクリーンアップされません

現在の実装では、結果データが保存される場所であるため、テストケースを保持します。将来的にはこれがより効率的になるように変更されますが、今のところそれは物事がどのように機能するかです。

4)「4」につながる:自分自身の後も片付ける必要があります

インスタンスは保持されているため、TestCaseメンバー変数も保持されます。

つまり、を使用することで多くのメモリを節約できます

public function tearDown() {
    unset($this->whatever);
}

しかし、そうすることは非常に退屈です。

私の提案は、すべてのTestCaseの基本テストクラスを用意し、これを使用することです。

class MyBaseTest extends \PHPUnit_Framework_TestCase {

    protected function tearDown()
    {
        $refl = new \ReflectionObject($this);
        foreach ($refl->getProperties() as $prop) {
            if (!$prop->isStatic() && 0 !== strpos($prop->getDeclaringClass()->getName(), 'PHPUnit_')) {
                $prop->setAccessible(true);
                $prop->setValue($this, null);
            }
        }
    }
}

これにより、自動化された方法で後片付けが行われます。

(スニペットの小道具は次の場所に移動します:http://kriswallsmith.net/post/18029585104/faster-phpunit


PHPUnitは、他の人のプロジェクトを壊さない下位互換性のある方法でこれを行うことはできないので、自分で追加する必要があります:)

于 2012-11-25T14:05:04.427 に答える
5

Calvin さん、チャットで説明したように、リセット機能がないことが原因でした。

テストするときは、正確な結果を得ることができるように、テスト環境が一貫していることを確認する必要があります。コンピューティングは入力/出力であるため、PHPUnit の Fixturesを使用してストレージをリセットし、このような「メモリ リーク」を防ぐ必要があります。

于 2012-11-24T02:15:29.357 に答える
1

PDO (または同様のデータベース抽象化) を使用している場合は、DSN として "sqlite::memory:" を使用できます。これには、次の 3 つの大きな利点があります。

  1. 各テスト後の自動クリアアップ
  2. 実稼働データベースに誤ってアクセスする可能性はありません (たとえば、実稼働サーバーで単体テストを実行する場合でも)。
  3. すべてメモリ内にあるため、テストがより速く実行される可能性があります

欠点は、SQL が MySQL と SQLite の間で移植可能でなければならないことです。これは非常に多くの作業になる可能性があります (より大きなプロジェクトでは、テストのためだけでなく、コードの設計を改善する方法のためにも価値があることがよくあります)。 、したがって、すでに適切な抽象化が行われている可能性があるため、SQLite で変更を加えなくても実行できる可能性があります。

于 2012-11-25T00:32:23.467 に答える