PHPベースの単体テストフレームワークであるSimpleTestを使用しています。データベースからのWebサイトコメントの保存と取得を処理する新しいコードをテストしています。データベースアクセスコードをテストするためにプロジェクトを構造化する方法に迷っています。
PHPアプリケーションでdbコードをテストするためのベストプラクティスに関する提案を探しています。例は本当に素晴らしいです。さらに読むためのサイトは素晴らしいです。
よろしくお願いします。:)
PHPベースの単体テストフレームワークであるSimpleTestを使用しています。データベースからのWebサイトコメントの保存と取得を処理する新しいコードをテストしています。データベースアクセスコードをテストするためにプロジェクトを構造化する方法に迷っています。
PHPアプリケーションでdbコードをテストするためのベストプラクティスに関する提案を探しています。例は本当に素晴らしいです。さらに読むためのサイトは素晴らしいです。
よろしくお願いします。:)
これは古い質問ですが、これに関して私たちが経験した特定の経験を追加したいと思いました。
他のポスターは、これが統合テストの形式であるという技術的に正しいですが、私が座っているところから、ユニットテストでスタブ化するには MySQL のロジックが多すぎることがよくあります。私たちと同じように、MySQL に大きく依存する大規模で複雑なサービス (および多くの場合、サービスごとに複数のテーブル) がある場合、テスト クエリ ロジックを含む堅牢なテスト フレームワークを使用すると非常に便利です。単体テストでかなりの数の依存関係をモックアウトしますが、MySQL はモックアウトしません。
この機能を提供するために simpletest をラップする一連のクラスがあります。次のように機能します。
tests/etc/schemas/table.sql
。これには、スキーマ データと、テストで検出される予定のすべての定型データの挿入が含まれます。Test_DbCase
、テーブルを構築する機能を提供するクラスを拡張します。loadTables('foo', 'bar')
の sql コマンドを実行します。foo.sql
bar.sql
table.sql
私たちが持っているもう 1 つのツールは、ファイルの作成を容易にする bash スクリプトです。これは非常に便利です。そうしないと手動で SQL を記述していたからです。既存のテーブル セットを取得し、MySQL ですべてのデータをセットアップし、それをエクスポートして基本的にテスト ファイルを作成できます。
これは私たちにとって非常にうまく機能しますが、最終的には自分で多くのことをロールバックする必要がありました.
既知の名前とデータベースのユーザー名/パスワードを使用した単体テスト専用のローカル データベースがありました。単体テストはその場所にハードコードされていましたが、必要に応じて別の開発者がこれらの変数をオーバーライドできました。
TRUNCATE
次に、各テーブルをテストする前に。これは、テーブルまたはデータベース自体を削除/作成するよりもはるかに高速です。
注:テスト後に切り捨てないでください。そうすれば、テストが失敗した場合に、問題の診断に役立つデータベースの現在の状態を確認できます。
PHP がデータを作成して一時テーブル/データベースに提供し、そのテーブル/データベースでテストできるようにしたい場合があります。その後、データベースを手動でリセットする必要はありません。ほとんどのフレームワークには、データベース操作を簡単にするためのライブラリがあります。フロントエンドでは時間がかかるかもしれませんが、後で変更を加えたときにテストをより迅速に行うことができます。
データベース コードをテストするときは、開始点と常に同じデータベースを使用することをお勧めします。特に単体テストを行う場合(ここではそうであると思います)。方法の 1 つは、Jason が提案したようにすべてのテーブルを切り捨てることですが、私はその中にいくつかの開始データを含めることを好みます。ご存知のように、各データベースに存在する「デフォルト」データが常に必要です。
また、一部のテストは完全なデータベースでのみ意味があります。したがって、これらのテスト用にデータベースの特別なインスタンスを作成します。いくつかのテストを実行する前に、プラグインする (ファイルをコピーするだけ) 約 3 つまたは 4 つの異なるデータベースがあります。毎回同じ開始点を持つことで、再現性が保証されます。
したがって、適切な「開始点」となるいくつかのデータベース状態を準備し、それらをバックアップするだけです。各テスト セットを実行する前に、適切なデータベースを復元してから実行します。
ORM を使用し、そのためのいくつかの統合テストを作成する必要があると思います。統合テストで実際の環境で完全に動作することが示された場合は、環境 (データベース、php バージョン、プラットフォームなど) を変更した場合にのみ、再度テストする必要があります。その後、ORM オブジェクトをモックアップできます。データベースに接続する必要はありません。
したがって、これが最善の方法だと思いますが、ORM を使用したくない場合は、テスト データベースを作成し、データベース接続 (PDO) オブジェクトをモックアップできます。その場合、testCases の setUp セクションと tearDown セクションでテスト テーブルを作成およびドロップできます。これらは単体テストではなく統合テストであることが重要です。そのため、常に実行する必要はなく、PHP と SQL サーバーの間で何かが変更された場合にのみ実行してください。統合テストでデータ アクセス オブジェクトをテストしたら、それらを単体テストでモックアップする必要があります。
データベースに対するテストは、通常、テスト対象のコードがカプセル化されていないことが原因で、不適切なテストを示します。データベースと対話するコードをコードの残りの部分からできる限り分離するようにしてください。この対話レイヤーを非常にシンプルに保ち、いくつかの非常に基本的なテストを実行できるようにします。
言い換えると; コメントを処理するコードは、データベースとのやり取りを処理するコードと同じであってはなりません。たとえば、コメントモデルがデータベースにアクセスするために使用する汎用テーブルモジュールを作成できます。テーブル モジュールをテストする必要がありますが、コメント コードとは別にテストする必要があります。
SimpleTest を使用してデータベース アクセス コードをテストしないことをお勧めします。
代わりに、たとえば Selenium を使用してアプリの機能テストを作成します。データベースの既知の状態から開始するときにテスト ケースを記録します。次に、コメントを追加し、(Selenium のアサートを使用して) コンテンツが実際に存在することを確認します。
このように: - セットアップと保守が容易 - DB レイヤーだけでなく、プレゼンテーション レイヤーも検証できます。
そうは言っても、DB にストアド プロシージャがある場合は、 SimpleTest を使用してください。私は自分で成功しました。基本的に、既知の DB 状態から開始する SimpleTests を作成し、いくつかの INSERTS/UPDATES を実行してから、ストアド プロシージャを実行し、DB の状態が期待どおりであることを確認します。
本当にデータベースに対してテストしたい場合は、各テストの前にデータをインポート/テーブルを作成することをお勧めします。そうすれば、データベースは各テストで既知の状態から開始されます。これはかなりパフォーマンスが高くつくため、 でトランザクションを開始し (rdms がサポートしている場合)、setUp
でロールバックできtearDown
ます。MySql (使用している RDBMS である可能性が高い) は、ネストされたトランザクションをサポートしていないため、テスト対象のコードがトランザクションを使用している場合、問題が発生する可能性があります。savepointsを使用して、これを回避できます。テスト前にセーブポイントを設定し、テスト後にセーブポイントにロールバックします。
これが必要な場合は、テストが何かを伝えようとしている可能性を考慮する必要があることを引き続き維持します..