あるテストを別のテストの結果に依存させる方法は?


13

他の多くのクラスがコードのあらゆる場所で使用する一般的な静的メソッドを提供するユーティリティクラスがあるとします。

ユーティリティテストのいずれかが合格しなかった場合にテストが失敗するように、ユーティリティのコンシューマ向けのユニットテストをどのように設計しますか?あなたはそれを行うことができますか、ユーティリティクラスのテストがすべてグリーンであるかどうかを自分で確認する必要がありますか?

たとえば、メッセージパーサーによって使用される(またはその出力)メッセージスプリッターユーティリティがあります。メッセージパーサーがテストされる前に、メッセージスプリッターが正しく動作することを確認したいと思います。

両方のテストを作成しましたが、それらをリンクし、1つのテストを他のテストの結果に依存させる方法はありますか?

これに適したタグが見つかりませんでしたが、Visual Studioの単体テストエンジンを使用しています。


1
ユーティリティが失敗した場合、パーサーが正しく動作しないことを理解しています。しかし、テストを実行すると、ユーティリティテストが失敗することがわかります。他のテストも失敗するのはなぜですか?
オイゲンマルティノフ

1
これを望んでいる人について聞いたことがありません。何を達成しようとしていますか?
エスベンスコフペダーセン


いくつかのユーティリティ関数を使用してパーサーテスト用のデータを準備するため、他のテストを行う前にユーティリティが正しく動作することを絶対に確認したいと思います。
t3chb0t

3
@ t3chb0tユーティリティが機能することを確認する場合は、ユーティリティを検証するユニットテストを作成する必要があります。単体テストはアトミックでなければなりません。単一のコンポーネントをテストしたいだけです。
maple_shaft

回答:


11

お使いのシステム内のすべての欠陥がトリップことを確認することにはポイントがありません正確に一つのテストが。

テストスイートには、1つのジョブがあります。既知の欠陥がないことを確認することです。欠陥がある場合、1つのテストが失敗しても10でも問題はありません。テストスイートの失敗に慣れた場合、失敗したテストをカウントしてプログラムの「悪さ」を測定しようとすると、回帰テストを正しい方法で使用します。テストスイートは、コードを公開する前にすべてのテストに合格する必要があります。

彼らは不完全な機能をテストする場合のテストをスキップするための唯一の正当な理由がある彼らはテストになっているものを実装しながら、あなたがより良い使用に置くことができると途方もない時間がかかります。(これは、厳密なテスト駆動開発を実践していない場合にのみ問題になりますが、それは結局のところ有効な選択です。)

それ以外の場合は、テストスイートを、何が問題なのかを正確に示すインジケーターにしようとしないでください。それは決して正確ではなく、そうであるはずもありません。これは、同じ間違いを2回犯さないようにするためのものです。それだけです。


8

それはあなたのツールに依存しますが、おそらくできないでしょう(すべきではありません)

いくつかの単体テストフレームワーク(PHPUnitを使用を例に)では、あるレベルで失敗したテストが他のテストを実行しないように、テストを「連鎖」できます。ただし、これでこの状況の問題が解決されるとは思いません。

保証されたテスト順序の実行を許可しないと、テストが相互に隔離され、一般的に良いことと見なされます。テストがそれ自体を実行するだけでなく、他のテストが動作するためのデータを提供する場合にどうなるか想像してみてください...

これらのユーティリティメソッドを別のソリューションまたはテストカテゴリに入れることができます。テストランナーで視覚的に「目立つ」こと、またはこのカテゴリのテストが失敗した場合、このカテゴリが最初に実行され、他のテストが実行されないことを確認してください*。これらのテストの1つが失敗すると、おそらくすべてのテストに失敗します。最初にこれらの失敗したテストを修正することで、テストを実行する人が開始を知っていることを確認する必要があります。ユニットテストと統合テストについても同じことが言えます。Unittestが失敗すると、カスケードされ、統合テストであらゆる種類の混乱が発生します。誰もが、Unit AND Integrationテストが失敗すると、Unittestsをチェックアウトすることから始まることを知っています...

*自動化されたビルドまたはテストスクリプトを使用すると、このカテゴリを最初に実行し、結果を確認し、この最初のテストバッチに合格した場合にのみ他のテストを実行できます。


5

単体テストをアトミックにしてください。自動化されたテストコードもコードベースの一部ですが、それ自体はテスト対象ではないため、できるだけシンプルでわかりやすいものにしてください。

より直接質問に答えるために、テストの実行順序の保証はないため、他のテストが実行される前にユーティリティテストが成功することを保証する方法もありません。そのため、すべてのテストに対して単一のテストスイートを使用しながら、目的を達成するための保証された方法はありません。

ユーティリティを独自のソリューションに移動し、現在のプロジェクトの結果のDLLへの参照を追加できます。


4

要約すると、ツール/テクニックを使用して、目的以外のことを行うことは望ましくありません。

しようとしていることは、CI(継続的インテグレーション)プラクティスで簡単に解決できる懸念のように聞こえます。

このようにして、既に提案されているようにテストをアトミックに保ち、CIにテストの検証を任せることができます。

テストが失敗した場合は、コードが公開されないように設定できます。


4

私は常にアプリケーションレベルのコードとフレームワークレベルのコードを区別しようとする習慣があるため、頻繁に説明する問題に遭遇しました。通常、アプリケーションレベルのコードをテストする前に、すべてのフレームワークレベルのコードをテストする。また、フレームワークレベルのコード内であっても、他のすべてのフレームワークモジュールで使用されるいくつかの基本的なフレームワークモジュールが存在する傾向があります。基本的に何かが失敗しても、他のテストはまったく意味がありません。

残念ながら、テストフレームワークの提供者は、その作成物がどのように使用されるのかについてある程度厳格なアイデアを持っている傾向があり、それらのアイデアをかなり保護していますが、フレームワークを使用する人々は質問することなく意図した使用を受け入れる傾向があります 実験と革新を抑制するため、これには問題があります。私は他の人については知りませんが、奇妙な方法で何かをしようとする自由があり、結果が確立された方法よりも良いか悪いかを自分で確かめたいのです。そもそも自分のやり方で物事を行う。

したがって、私の意見では、テストの依存関係は素晴らしいものであり、その代わりに、テストを実行する順序を指定する機能が次善の策です。

テストの順序付けの問題に対処するために見つけた唯一の方法は、テストフレームワークがアルファベット順にテストを実行する傾向を利用するために、慎重に命名することです。

これがVisual Studioでどのように機能するかはわかりません。C#での広範なテストを行う必要があるためです。しかし、Javaの世界では次のように機能します。プロジェクトのソースフォルダーの下には、通常2つのサブフォルダーがあり、生産コードを含む「メイン」と呼ばれるものと、テストコードを含む「テスト」と呼ばれるものです。「メイン」の下に、ソースコードのパッケージ階層に正確に対応するフォルダー階層があります。Javaパッケージは、C#名前空間にほぼ対応しています。C#では、フォルダー階層を名前空間階層に一致させる必要はありませんが、そうすることをお勧めします。

現在、Javaの世界で通常行われているのは、「テスト」フォルダーの下で「メイン」フォルダーの下にあるフォルダー階層をミラーリングすることです。したがって、各テストは、テストするクラスとまったく同じパッケージに存在します。この背後にある理論的根拠は、テストクラスがテスト対象クラスのパッケージプライベートメンバーにアクセスする必要があることが非常に多いため、テストクラスはテスト対象クラスと同じパッケージにある必要があるということです。世界のC#側には、名前空間ローカルの可視性などはありません。したがって、フォルダー階層をミラーリングする理由はありませんが、C#プログラマーは、フォルダーを構造化する際にほぼ同じ規律に従うと思います。

いずれにせよ、実装ではなくインターフェイスをテストする傾向があるため、テストクラスがテスト対象クラスのパッケージローカルメンバにアクセスできるようにするというこの考え全体は見当違いです。そのため、テストのフォルダー階層は、実動コードのフォルダー階層をミラーリングする必要はありません。

だから、私がやることは、私のテストのフォルダ(つまり、パッケージ)に次のように名前を付けることです:

t001_SomeSubsystem
t002_SomeOtherSubsystem
t003_AndYetAnotherSubsystem
...

これにより、「SomeSubsystem」のすべてのテストが「SomeOtherSubsystem」のすべてのテストの前に実行され、さらに「AndYetAnotherSubsystem」などのすべてのテストの前に実行されることが保証されます。

フォルダー内では、個々のテストファイルの名前は次のとおりです。

T001_ThisTest.java
T002_ThatTest.java
T003_TheOtherTest.java

もちろん、最新のIDEが強力なリファクタリング機能を備えているため、パッケージ全体(およびすべてのサブパッケージ、およびそれらを参照するすべてのコード)を数回のクリックとキーストロークで名前変更できます。


2
I don't know about everyone else, but I would prefer to have the freedom to try to do something in an odd way, and see for myself whether the results are better or worse++ mate。私は解決策が好きだとは知りませんが、あなたがそこに示した態度が好きです。
ラバーダック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.