テストの種類とアプリケーションへのアプローチ

プログラミングテクノロジーの研究所のコースから、テストの種類を次のように分類しました(基準はコードの分離の程度です)。 テストが行​​われます: 分類は明確で明確です。 ただし、実際には、各タイプのテストには独自の特性があることがわかります。 そして、それらが考慮されない場合、テストは面倒になり、適切に処理されません。 ここでは、さまざまな種類のテストの実際のアプリケーションへのアプローチを集めました。 そして.NETで書いているので、リンクは対応するライブラリになります。



ブロックテスト



ブロック(単体テスト)テストは、プログラマーにとって最も理解しやすいものです。 実際、これはプログラムのクラスのメソッドを、他のプログラムから分離してテストしています。



すべてのクラスが単体テストで簡単にカバーできるわけではありません。 設計するときは、テスト可能性とクラスの依存関係を明示的に示す可能性を考慮する必要があります。 テスト容易性を保証するために、 TDD方法論を適用できます。最初にテストを記述し、次にテストメソッドの実装コードを記述する必要があります。 次に、アーキテクチャがテストされます。 依存関係の解明は、 Dependency Injectionを使用して実行できます。 次に、各依存関係がインターフェイスに明示的にマップされ、コンストラクター、プロパティ、またはメソッドへの依存関係の注入方法が明示的に決定されます。



単体テストには特別なフレームワークがあります。 たとえば、 NUnitまたはVisual Studio 2008のテストフレームワーク。クラスを分離してテストするために、特別なMockフレームワークがあります。 たとえば、 Rhino Mocks 。 これらにより、インターフェイスは依存関係クラスのスタブを自動的に作成し、それらに必要な動作を設定できます。



単体テストでは、多くの記事が書かれています。 MSDNの記事「時間と涙を節約できる保守可能な単体テストの作成」は、時間の経過とともに保守が面倒にならないテストを作成する方法を明確かつ明確に説明しています。



統合テスト



私の意見では、統合テストは最も理解しにくいものです。 定義があります-これは、ある種の作業を一緒に実行するいくつかのクラスの相互作用をテストしています。 しかし、そのような定義でテストする方法は明確ではありません。 もちろん、他の種類のテストに基づいて構築することもできます。 しかし、それは困難です。



テストで依存関係がモックオブジェクトに置き換えられない単体テストとしてアプローチすると、問題が発生します。 相互作用するコンポーネントの可能な組み合わせの数は多項式依存であるため、カバレッジを良好にするには、 多くのテストを記述する必要があります。 さらに、単体テストでは、相互作用の実行方法をテストします( ホワイトボックステストを参照)。 このため、リファクタリング後、何らかの相互作用が新しいクラスに割り当てられることが判明した場合、テストは失敗します。 より侵襲性の低い方法を使用する必要があります。



また、より詳細なシステムテストとして統合テストに取り組むこともできません。 この場合、逆に、プログラムで使用されるすべての相互作用をチェックするテストはほとんどありませ 。 システムテストのレベルが高すぎます。



統合テストに関する優れた記事に出会ったのは、 シナリオ駆動テストだけです。 彼女とAooendeのBooの DSL DSLに関する本、.NETのドメイン固有言語の本を読んだ後統合テストを調整する方法を思いつきました。



アイデアはシンプルです。 入力データがあり、プログラムがその上でどのように機能するかを知っています。 この知識をテキストファイルに書き込みます。 これは、プログラムからどのような結果が期待されるかを記録するテストデータの仕様になります。 テストにより、仕様への準拠とプログラムが実際に見つけたものが判断されます。

例で説明します。 プログラムは、1つのドキュメント形式を別の形式に変換します。 変換は複雑で、数学的計算が必要です。 顧客は、変換する必要がある一連の典型的なドキュメントを引き渡しました。 このようなドキュメントごとに、変換時にプログラムが到達するすべての中間結果を書き留める仕様を作成します。



1)提出された文書にいくつかのセクションがあるとしましょう。 次に、仕様で、解析されたドキュメントに指定された名前のセクションがあることを示すことができます。



$SectionNames = , , ,







2)別の例。 変換するときは、幾何学的形状をプリミティブに分割する必要があります。 すべてのプリミティブが元の図形を完全にカバーしている場合、パーティションは成功したと見なされます。 送信されたドキュメントから、さまざまな図を選択し、それらの仕様を記述します。 図形がプリミティブで覆われているという事実は、次のように反映できます。



$IsCoverable = true



このような仕様を確認するには、仕様を読み取り、プログラムの動作への準拠を確認するエンジンが必要であることは明らかです。 このようなエンジンを作成し、このアプローチに満足しました。 すぐにエンジンをオープンソースに投稿します。 (UPD: レイアウト



このタイプのテストは統合テストです。これは、チェック時にいくつかのクラスの相互作用のコードが呼び出されるためです。 さらに、相互作用の結果のみが重要であり、呼び出しの詳細と順序は重要ではありません。 したがって、コードのリファクタリングはテストに影響しません。 過剰なテストや不十分なテストはありません。実際のデータを処理するときに発生する相互作用のみがテストされます。 仕様は読みやすく、新しい要件に合わせて簡単に変更できるため、テスト自体のメンテナンスは簡単です。



システムテスト



システム-これはプログラム全体をテストしています。 小さなプロジェクトの場合、これは通常、手動テストです-起動、クリック、動作確認(動作しない)を確認します。 自動化できます。 自動化には2つのアプローチがあります。



最初のアプローチは、MVCパターンのバリエーション- パッシブビューMVCパターンのバリエーションに関する別の良い記事)を使用し、コード内のGUIとのユーザーインタラクションを形式化することです。 次に、システムのテストは、Presenterクラスのテストと、View間の遷移のロジックになります。 しかし、ニュアンスがあります。 システムテストのコンテキストでPresenterクラスをテストする場合、可能な限り少ない依存関係をモックオブジェクトに置き換える必要があります。 そして、ここで、テストを開始するのに必要な状態にプログラムを初期化し、もたらす問題が現れます。 上記のシナリオ駆動テストの記事では、これについて詳しく説明しています。



2番目のアプローチは、特別なツールを使用してユーザーアクションを記録することです。 つまり、その結果、プログラム自体が起動しますが、ボタンのクリックは自動的に実行されます。 .NETの場合、そのようなツールの例はWhite libraryです。 WinForms、WPF、および他のいくつかのGUIプラットフォームがサポートされています。 ルールはこれです-ユースケースごとに、ユーザーのアクションを記述するスクリプトに記述されています。 すべてのユースケースがカバーされ、テストに合格した場合、システムを顧客に提供できます。 受け入れ証明書に署名する必要があります。



All Articles