データベースの単体テストを行うにはどうすればよいですか?
-
04-10-2019 - |
質問
データベースを使用するアプリケーションを開発するときは、データベースの単体テストを行う必要があると聞いたことがあります。データベース単体テストのベスト プラクティスは何ですか?db 単体テストを行う際の主な懸念事項は何ですか?また、それを「正しく」行う方法は何ですか?
解決
データベース単体テストのベスト プラクティスは何ですか?
の Dbユニット フレームワーク (データベースを既知状態にし、その内容に対してアサーションを実行できるテスト フレームワーク) には、データベース テストをリストするページがあります。 ベストプラクティス 私の経験では、それは真実です。
DB単体テストを行う際の主な懸念事項は何ですか
- 最新のスキーマの作成、スキーマ変更の管理
- データ(リファレンスデータ、テストデータ)の設定と 維持する テストデータ
- テストの独立性を維持する
- 開発者が同時に作業できるようにする
- 速度 (データベースを含むテストは通常遅く、ビルド全体にかかる時間が長くなります)
そしてそれを「正しく」行うにはどうすればよいでしょうか?
ヒントにあるように、既知のグッド プラクティスに従い、専用のツール/フレームワークを使用してください。
- 可能であればメモリ内データベースを推奨します (速度向上のため)
- 開発者ごとに 1 つのスキーマを使用することが必須です (同時作業を可能にするため)
- 「データベース移行」ツール (RoR 版) を使用してスキーマの変更を管理し、スキーマを最終バージョンに更新します
- テスト ハーネスを構築または使用すると、各テストの前にデータベースを既知の状態にし、実行後にデータに対してアサートを実行できます (または、テストの最後にロールバックするトランザクション内でテストを実行できます)。
他のヒント
データベース単体テストを開始するときに確認および考慮する必要がある項目のリスト
- 他のテスター/開発者の活動の干渉を避けるために、各テスターには個別のデータベースが必要です。
- テスト対象のデータベースを簡単に作成できるようにするため (これは、SQL Server データベースをバージョン管理下に置くことに関連します)。これは、一部のテストが失敗した場合に、何が問題になったのかを見つけようとする場合に特に役立ちます。
- 一度にすべてをカバーするのではなく、特定の領域に焦点を当て、単一モジュールのテストを作成します。テストを細かく追加するのは効率を上げる良い方法です
- テストが失敗した場合は、デバッグを容易にするために、できるだけ多くの詳細を提供してください。
- すべてのテストに 1 つの同じテスト データを使用する
tSQLt フレームワークを使用してテストが実装されている場合、複数の SQL Server インスタンスからの大量のデータベースを扱う場合、単体テスト プロセスが複雑になる可能性があります。SQL Server Management Studio から直接単体テストを保守、実行、管理するには、 ApexSQL 単体テスト 解決策として使用できます
を見てみましょう このリンク. 。これは、SQL Serverに保存されたProcsと、さまざまな種類の単位テストとそれらを使用する必要がある単位テストを作成するための基本のいくつかを超えています。使用しているDBMSはわかりませんが、明らかにこの記事はSQL Server向けです。
記事から盗まれた:
機能テスト
データベースユニットテストの最初で最も一般的なクラスのクラスは、機能テストです。私の考えでは、機能テストは、データベース消費者の観点からデータベースのコア機能(またはAPI)をテストします。データベースのプログラマ性オブジェクトのテストは、ここではメインラインシナリオです。したがって、データベース内のすべてのストアドプロシージャ、機能、トリガーをテストすると、私の心の中の特徴テストが構成されます。ストアドプロシージャをテストするために、ストアドプロシージャを実行し、予想される結果が返されたか、適切な動作が発生したことを確認します。ただし、これらのタイプのオブジェクト以上のものをテストできます。たとえば、計算された列から適切な計算を返すように、ビューを確実にしたいと思うことを想像できます。ご覧のとおり、この領域の可能性は大きいです。
スキーマテスト
データベースの最も重要な側面の1つは、そのスキーマであり、テストして、それが期待どおりに動作することを確実にすることであり、データベース単位テストの別の重要なクラスです。ここでは、適切な順序で適切なデータ型の予想される列のセットをビューが返すようにすることがよくあります。実際、データベースに予想される1,000台のテーブルが含まれていることを確認することをお勧めします。
セキュリティテスト
今日の時代には、データベース内に保存されているデータのセキュリティが重要です。したがって、データベース単位テストの別の重要なクラスは、データベースセキュリティをテストするものです。ここでは、特定のユーザーがデータベースに存在し、適切なアクセス許可が割り当てられていることを確認する必要があります。多くの場合、制限付きテーブルまたはビューからデータを取得し、アクセスが適切に拒否されていることを確認する否定的なテストを作成する必要があります。
ストックデータテスト
多くのデータベースには、ストックデータまたはシードデータが含まれています。このデータはまれに変化し、アプリケーションまたはエンドユーザーのルックアップデータとしてよく使用されます。 ZIPコードとそれに関連する都市と州は、この種のデータの優れた例です。したがって、テストを作成して、実際に株式データがデータベースに存在するようにすることが有用です。
テスト全般ではなく、単体テストについて質問していただいてうれしいです。
データベースにはテストが必要な機能が多数あります。いくつかの例:
- データ型/サイズ/文字セット (スウェーデン語の名前、現実世界の長い URL または数字を挿入してみて、列の定義が適切かどうかを確認してください)
- トリガー
- 制約 (外部キー、一意性など)
- ビュー (データが正しく含まれる/除外される/変換されることを確認する)
- ストアド プロシージャ
- UDF
- 権限
- ...
これは、データベース内の何かを変更する場合だけでなく、dbms をアップグレードする場合や設定の何かを変更する場合にも役立ちます。
通常、統合テストは行われます。これは、PHP や Java などのプログラミング言語でテスト スイートが作成され、テストがいくつかのクエリを発行することを意味します。しかし、何かが失敗したり、いくつかの例外がある場合、次の 2 つの理由により、問題を理解するのが難しくなります。
- 問題は、PHP コード、PHP 設定、ネットワーク、または...にある可能性があります。
- SQL ステートメントが別のプログラミング言語に埋め込まれている場合、SQL ステートメントの読み取りと変更が難しくなります。
したがって、私の意見では、複雑なデータベースの場合は、(ストアド プロシージャとテーブルを使用して) SQL で書かれた単体テスト フレームワークを使用する必要があります。この種のツールは広く使用されていない (したがって、広くテストされていない) ため、慎重に選択する必要があります。たとえば、MySQL を使用している場合は、次のツールを知っています。
- STK/ユニット http://stk.wikidot.com/stk-unit
- utMySQL http://utmysql.sourceforge.net/
Junit/nunit/etcを使用し、JavaまたはC#でデータベースユニットテストをコードアップします。これらは、おそらくテストデータベースに別のスキーマを使用して統合サーバーで実行できます。
最新のOracle SQL開発者には、組み込みのユニットテストフレームワークが付属しています。私はこれを調べましたが、そうします いいえ これを使って。 GUIを使用してテストを作成および実行し、データベース内のすべてのテストを保存するため、テストケースをバージョン制御下に置くのはそれほど簡単ではありません。おそらく他のテストフレームワークがありますが、それらはあなたのデータベースに固有のものであると思います。
グッドプラクティスは、定期的なユニットテストに似ています。
- テストをソース制御下に置きます
- 速く実行されるテストを行う - 一度にテストしすぎないでください
- テストを再現可能にします
DBTESTDRIVENフレームワークをご覧ください。それは私たちにとってうまく機能します。 GithubまたはそのWebサイトからダウンロードしてください。
JVM開発に関しては、単体テストはJDBC抽象化の恩恵を受けることができます。どのJDBCデータがDBアクセスによって提起されているかがわかるとすぐに、これらのJDBCデータを「再生」できます。
したがって、DBアクセスケースは、ターゲットDBなしでテスト用に「複製」できます。テスト/データの複雑さなし、継続的な統合を容易にします。
私のフレームワークAcolyteは、この方法で役立つフレームワークです(DB結果を「記録」するためのStudio GUIツールを含む): https://github.com/cchantep/acolyte