web-dev-qa-db-ja.com

ストアドプロシージャを適切に利用する大規模なプロジェクトに単体テストを追加する最良の方法を決定する

私たちはかなり大きなカジノ/ゲーム/財布/宝くじのプラットフォームに取り組んでいます。これは、4つのクライアントで現在使用されているターンキーアプリケーションであり、間もなくさらに多くの機能を提供します。以下のアーキテクチャに関していくつかの箇条書きを行いました。

  • C#コードのみで〜130K LOC
  • システムが使用する5つのデータベースのうちの1つにある500を超えるストアドプロシージャ-コードは規制された環境で使用されるため、(非常に高価な)外部機関によってレビューされるまで、一部のクライアントに対してソースコードが「ロック」され、変更が加えられます。ストアドプロシージャを介することは、規制当局とクライアントの両方を満足させる良いバランスです。他のデータベースは、「メイン」データベースの複雑さに近くありません。
  • C#アプリケーションコード、Windowsフォーム、Xamarin Android、Windowsサービス、Webアプリ、SQL CLRライブラリ、クラスライブラリ、ユニットテストプロジェクトに分散
  • データレイヤー、アドホック、ストアドプロシージャの一部にEF6を使用します

いくつかの単体テストが実施されていますが、それは主にインフラストラクチャ関連のものです。ビジネス機能をテストするテストはそれほど多くありません。もう1つの問題は、手間のかかる作業の多くがストアドプロシージャで行われることです。回帰を防ぐために、コードの一部をリファクタリングする前に、いくつかの単体テストを追加するときがきました。私が探しているのは、これに対処するためのさまざまな方法のリストです。これは私がこれまでに思いついたものです:

  • 各テストを開始するときにデータをクリアして再入力するように設定できる「テスト」SQL Serverインスタンスがあります。
    • 長所
      • 新しいテストを追加するときに、データのクリア/リロードスクリプトを簡単に変更できます
    • 短所
      • クリア/リロードスクリプトは巨大になる可能性があります
      • テストの実行ごとにデータをクリア/再ロードするため、テストが遅くなる可能性があります
  • SOで読んだMoqを使用してEF6データコンテキストをモックすることができます
    • 長所
      • データはC#コードから取得され、コンパイルされるため、テストは高速です。
    • 短所
      • C#でテストデータを追加すると、時間がかかります
  • mstestを使用してストアドプロシージャを使用しないC#プロシージャをテストし、RedgateのSQLテスト製品を使用してSQLプロシージャを単独でテストする
    • 長所
      • わからない。 Redgate製品の開発者スイートを所有していますが、これまでにSQLテストを使用したことはありません。
    • 短所
      • 私の意見では、プロシージャの内部動作の真のテストではありません
  • データベースをQAサーバーに強制的にロードし、接続に新しいSqlTransactionを作成し、破棄されるとRollbackを呼び出して破棄するEFデータコンテキストの新しいオーバーライドを作成します行われたすべての変更
    • 長所
      • 既存のコードの多くの内部への多くの変更、またはリファクタリングを必要としません
    • 短所
      • データベース接続を作成するのではなく、データベース接続を取り込むために、一連のコードをリファクタリングする必要があります。データベース接続を取得するためのIOC

私が持っている計画は、いくつかの優れたテストを作成することです。カードに多くのリファクタリングが含まれていない場合は、QA担当者に、すべてを設定しながら作成された例に基づいてテストを作成することでプログラミングを学んでもらいます。

大規模なプロジェクトに単体テストを追加するにはどうすればよいですか?データベース内のストアドプロシージャを呼び出すテストプロシージャをどのように処理する必要がありますか? 私が知りたいのは、多くのリファクタリングなしで単体テストをシム化するための最良の方法です。このコードベースをリファクタリングしてデータレイヤーを分離することは、一部のスポットでは難しくありませんが、他のスポットではやりにくいので、摩擦が最も少ない方法が最善です。

7
Derreck Dean

ストアドプロシージャとそれを使用するC#コードは異なるユニットであるため、1つのユニットテストで両方をテストすることはできません。個別の単体テストが必要です。

  • ストアドプロシージャをモックし、C#コードがそれを正しく使用していることを確認する単体テスト。
  • ストアドプロシージャをアクティブ化する単体テストは、C#コードがそれをアクティブ化するのと同じ方法で(本当に必要な場合は、C#コードを偽造していると言えます)、ストアドプロシージャが想定どおりに機能することを確認します。

両方の箇条書きの単体テストでは、C#コードとストアドプロシージャの間のインターフェイスは同じままであると想定しています。しかし、リファクタリングを計画している場合は、そのインターフェースをリファクタリングする可能性が高いでしょう。ユニットテストはあなたを保護しません:インターフェースが変更された場合、両方のモックは古くなっており、テストを書き直す必要があります!

単体テストに焦点を当てるのではなく、統合テストにさらに焦点を当てるべきであることをお勧めします。つまり、1つのテストでC#コードとそれが使用するストアドプロシージャの両方をテストできます。これは、データベース(データのみ)をモックする必要がないため、テストの作成がはるかに簡単になることも意味します。

各テストでトランザクションを使用できるかどうかを確認してください。 BEGINテストを開始する前のトランザクション、およびテストの後でROLLBACKトランザクション。そうすれば、テストごとにデータベースにデータを再入力する必要がなくなります。セッションのすべてのテストで同じ初期データベースが使用され、フレームワークはその後にクリーンアップします。

5
Idan Arye