11

関数を使用してデータベースからデータを取得し、表示/解析/その他する結果を返す Web サイトがあるとします。

データベースから取得されるデータは動的であり、1 秒ごとに変更される可能性があるため、この関数の単体テストを適切に作成するにはどうすればよいでしょうか?

関数が結果の配列を返すことになっているとしましょう。明らかに、単体テストで配列が返されるかどうかを確認できます。しかし、MySQL クエリが正しく記述されていないために、配列自体の内容が正しくない場合はどうなるでしょうか? 配列のサイズがゼロであるか、配列の内容が正しくない可能性があります。絶えず変化するデータに依存しているため、単体テストは何が正しくて何が正しくないかをどのように判断するのでしょうか? 単体テスト自体からデータベースへの呼び出しが必要になるので、比較するものがありますか?

動的データに依存する関数の単体テストを適切に作成するにはどうすればよいですか?

4

6 に答える 6

10

単体テストは、理想的な形では、1 つのことだけをテストする必要があります。この場合、次の 2 つのことをテストします。

  1. 関数のロジック
  2. データベース検索

したがって、次のリファクタリングをお勧めします。

  1. データベース取得ロジックを別の関数に移動
  2. テストしたい関数に他の関数を呼び出させる
  3. アプリのロジックのみを単体テストできるように、データを返す関数をモックアウトします。
  4. それが理にかなっている場合 (これを行うために別のライブラリに依存している場合は、lib に既にテストがあることを願っています)、動的検索関数の単体テストを作成します。ここでは、詳細をテストすることはできませんが、返されたデータの構造と妥当性 (たとえば、すべてのフィールドが設定されており、現在から 5 秒以内の時間です)。

また、通常は、データベースに格納される内容を完全に制御できるテスト環境で単体テストを実行することをお勧めします。これらを本番データに対して実行する必要はありません。

于 2012-04-23T20:56:29.230 に答える
2

関数がデータベースからデータを引き出す以外に興味深いことを行う場合は、取得を別の関数に抽出してモックする必要があります。そうすれば、残りをテストできます。

これでも、データベース アクセスをテストするタスクが残ります。そのための単体テストを実際に行うことはできません。これは、定義によりデータベースにアクセスせず、必要と思われるSQLステートメントを送信するかどうかをテストできますが、SQLステートメントが実際に機能するかどうかはテストできません。

だからデータベースが必要

さまざまなオプションがあります。

1) テストによって変更されない、そのようなテスト用の固定データベースを作成します。

長所: 概念的に簡単 短所: 保守が難しい。テストは同じデータに依存するため、相互依存になります。更新、挿入、または削除を行うものをテストする方法はありません (DDL は言うまでもなく)

2) テスト中にデータベースを作成します。ここで、テスト用のデータベースのセットアップとデータの入力という 2 つの問題があります。

セットアップ:

1)テストを実行する必要があるすべての人(少なくとも開発者+ ci-server)のユーザー/スキーマ/データベースを使用して、データベースサーバーを実行します。スキーマは、休止状態や展開に使用するスクリプトなどを使用して作成できます。

うまく機能しますが、昔ながらの DBA を夢中にさせます。アプリケーションはスキーマ名に依存してはなりません。アプリで複数のスキーマが使用されている場合にも問題が発生します。このセットアップはかなり遅いです。高速ディスクに入れるのに役立ちます。RAM ディスクのように

2) インメモリデータベースを持っています。コードから簡単に開始でき、高速です。ただし、ほとんどの場合、本番データベースと同じように動作します。違いを隠そうとするものを使用する場合、これはあまり問題になりません。私はよく、最初のビルド段階でインメモリ データベースを使用し、2 番目の段階で実物を使用します。

テストデータのロード

1) 人々は私に dbunit を使うように言います。XML が大量にあり、列や制約が変更されたときに維持するのが難しいとは思えません。

2) 通常のアプリケーション コードを好みます。私の場合は(Java + Hibernate)ですが、本番環境でデータをデータベースに書き込むコードは、多くの場合、テスト用のテストデータを書き込むのに適しているはずです。すべての外部キーなどを満たすための詳細を隠す、少し特別なAPIがあると役立ちます。-1-one-to-rule-them/

于 2012-04-23T21:15:43.087 に答える
1

あなたがDBについて話しているという事実を無視して、あなたはあらゆる不測の事態をカバーするユニットテストを探しているかもしれません. 私があなたなら、標準的なパスをカバーし、次にいくつかのエッジ ケースをカバーします。実際には、すべてを実際にテストすることはできません。

ここにいくつかのさらなる読書があります

http://37signals.com/svn/posts/3159-testing-like-the-tsa
単体テストの深さは?
http://johnnosnose.blogspot.co.uk/2012/04/re-over-testing.html
http://martinfowler.com/bliki/TestCoverage.html

特定のデータベース関連の問題を見ると、この関数をテストするには、おそらくデータを事前に入力するための継ぎ目を作成して、それらのケースをカバーできるようにする必要があります。

于 2012-04-23T21:01:27.380 に答える
1

テスト自体でデータを構築します。そうすれば、絶えず変化するデータに対して複雑なシナリオをテストすることもできます。重要な点は、専用のテスト データベースを用意することで、テストのデータ変更を制御できることです。

ステップ 1: 必要なデータをテストでのみ使用されるデータベースに挿入します ステップ 2: データベースは安定した予測可能な状態になったので、クエリを実行して出力をテストできます

于 2012-04-24T05:01:26.567 に答える
1

ほとんどのテストは、データの取得などに関係するロジック パスに焦点を当てています。データ自体の有効性についてではありません。データの有効性は、アプリケーションが何らかの方法でデータを計算または集計している場合にのみ意味があります。その場合、入力を制御して結果が正しいことを確認できる必要があります。

とはいえ、アプリが返品を確認するために使用しているのと同じデータベースにアクセスしたい場合もあります。たとえば、フィルター処理されたデータセットを返す関数をテストしている場合、単体テストで同じクエリを実行してから、たとえば各レコードの主キーの行ごとの比較を行い、関数が期待していたのと同じデータセット。

これがあなたの特定の質問であるかどうかはわかりませんが、逆に、単体テストでアサートを実行するためにデータベースにアクセスしても問題はありません。少なくとも私はいつもそうしていますし、誰も私を逮捕させようとしたことはありません:)

于 2012-04-23T20:56:11.007 に答える
1

あなたは本当にできません。信頼できる単体テストを作成するには、保証された静的データ セットが必要です。おそらく、データベース スナップショットが役に立ちます。

動的データは、回帰テストの実行など、他の方法でも役立ちます...

于 2012-04-23T20:55:35.897 に答える