8

私のウェブサイトには高度な検索があります。人々はそこに行き、エンティティー (例えば車) について検索することができます。検索パラメーターに基づいて結果の数をチェックするいくつかのテストを作成しました。どのテストを書くべきかを考え、それを書き、テスト データベースにデータを追加します。しかし、ここで問題が発生します。データベースに新しい値を挿入すると、古いテストが壊れます。それは、レコード数をチェックしているからです...

<?php defined('SYSPATH') or die('No direct access allowed!');

class Search_Test extends PHPUnit_Extensions_Database_TestCase
{
    /**
     * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection
     */
    public function getConnection()
    {
        $pdo = new PDO('mysql:dbname=db_test;host=127.0.0.1', 'root', null);
        return $this->createDefaultDBConnection($pdo, 'db_test');
    }

    /**
     * @return PHPUnit_Extensions_Database_DataSet_IDataSet
     */
    public function getDataSet()
    {
        $fixture = realpath(dirname(__FILE__).'/../data/fixture.xml');
        return $this->createXMLDataSet($fixture);
    }

    public function numberOfResultsDataProvider()
    {
        return array(
            array(1, null, null, 1),
            array(2, null, null, 3),
            array(3, null, null, 0),
            array('abc', null, null, 5),
            array(null, 1996, 2003, 3),
            array(null, 1996, 1999, 2),
            array(null, 2002, 2003, 1),
            array(null, 1500, 1800, 0),
            array(null, 2003, 2003, 1),
            array(null, null, 2005, 4),
            array(null, 1996, null, 4),
            array(null, null, null, 4),
            array(null, 2003, 1996, 0),
            array(null, 'abc', 2003, 4),
            array(null, '1996', '1999', 2),
            array(2, 2003, 2005, 2),
            array(null, null, null, 4),
        );
    }

    /**
     * @dataProvider numberOfResultsDataProvider
     */
    public function testNumberOfResults($brandId, $startYear, 
        $endYear, $numberOfResults
    ) {
        $search = ORM::factory('search');
        $search->setBrand($brandId)
            ->setYearRange($startYear, $endYear);
        $results = $search->results();
        $this->assertEquals($results->count(), $numberOfResults);
    }
}
?>

それは正常ですか?新しいテストを作成すると、古いテストが壊れる必要がありますか?

テストをデータにバインドする必要がありますか?

検索のパラメーターが多すぎるため、同じフォーム (ビュー) で使用されます。各パラメーターを検索するテストを作成する必要がありますか、それとも一緒にテストする必要がありますか? もっと多くのテストクラスに分割する必要がありますか?

ありがとう。

4

5 に答える 5

6

データベースを含む単体テストを実行する場合、テストでは、テスト対象の実際のデータベースを提供する必要があります。一致する 1 つの行と一致しない 1 つの行など、テストに関連する値のみを含む単純なデータベースである可能性があります。特定の時点で存在していたライブ データベースのスナップショットに対して一連のテストを作成することも合理的です。

これを達成するための特に便利な方法の 1 つは、テスト専用の Sqlite3 データベースを用意し、それをテストに使用するようにアプリケーションを設定することです。

于 2011-09-13T23:19:27.723 に答える
1

要するに:
ライブデータベースでこれを行う方法はありません

テスト用に別のデータベースが必要です。これは実際にはデータベースのモックかもしれません。

次に、テストの前に、データベースが期待どおりの固定状態になるように準備する必要があります (フィクスチャからデータをロードする、SQL ファイルをインポートするなど)。

次に、元のデータベースの状態を変更する予定がある場合は、データベース トランザクションを開始するのが最適なオプションです。

トランザクションが開始されると、データベースで作業できます。

テストが完了したら、トランザクションをロールバックして、データベースをクリーンな状態にします。

Sqlite (前述) はほとんどの場合問題なく動作しますが、実際のデータベースとは異なる場合があります。いずれにせよ、異なるデータベースアダプタを使用することは非常に役立ちます。

于 2011-09-14T16:14:45.967 に答える
1

可能であれば、コードがデータをフェッチする方法とデータベース自体との間のリンクを切断する必要があります。単体テストはデータベースに依存するべきではありませんが、いくつかの理由に遭遇しました: テスト間でデータを維持する必要がある、新しいテストを作成すると他のテストが壊れるなどです。何らかの方法でデータ アクセス ポイントを偽造し、厳密にメモリ内にデータを返すことができれば、それは理想的なケースです。PHP でそれがどれほど簡単かはわかりませんが、データ アクセス コードの周りにインターフェイスを構築し、そのインターフェイスのフェイク/モック化された実装を使用すると、この目標を達成するのに大いに役立つ可能性があります。

于 2011-09-14T00:21:57.627 に答える
0

新しいテストを作成するときにテストが壊れてはならず、テストはデータ依存してはなりません。データベース内の特定のデータを必要とするテストでは、そのデータをデータベースに配置する必要があります。また、データベースに他のデータがないようにする必要がある場合は、他のすべてを消去する必要があります。

もちろん、これによりテストが遅くなります。そのため、データ アクセス レイヤーをモック アウトします。

于 2011-09-13T23:20:28.720 に答える
0

各テスト メソッドに独自のデータを作成させ、次に独自のサンプル データを検索、アサート、破棄します。

通常、共有の addData() メソッドを使用し、次にデータベースのクリーンアップ メソッドを使用します。追加したデータをなんらかの方法で識別できるようにして、クリーンアップ方法を一般的なものにできることを願っています。あなたの例では、おそらくすべての brandId を「test-」で開始すると、クエリは brandId が「test-%」のようなすべてのレコードを検索して削除します。

于 2011-09-14T02:54:56.880 に答える