7

現在、自分のコードに対して別のプロジェクトの JUnit 4 テストを再利用しています。自動化された Ant ビルドの一部として、他のプロジェクトのリポジトリから直接それらを取得します。これは、最新バージョンのテストに対してコードをグリーンに保つことができるため、素晴らしいことです。

ただし、私のコードで絶対に渡さないと思われるテストのサブセットがあります。しかし、これらのテストに @Ignore アノテーションを追加し始めると、テスト実装の独自の別のコピーを維持する必要があり、これは本当にやりたくないことです。

テスト ソースを変更せずに個々のテストを除外する方法はありますか? これが私がこれまでに見たものです:

  • 私が見る限り、Ant JUnit タスクでは、個々のテスト メソッドではなく、テスト クラス全体を除外することしかできません。

  • リフレクションを使用して元のテストをすべて動的に検索して追加し、実行したくないテストを明示的に削除するコードを追加する TestSuite をまとめることを検討しました。しかし、 TestSuite APIがテストを削除する方法を提供していないことに気付いたとき、私はその考えを捨てました。

  • 元の Test クラスを拡張する独自の Test クラスを作成し、実行したくない特定のテストをオーバーライドして、@Ignore で注釈を付けることができます。次に、サブクラスで JUnit を実行します。ここでの欠点は、新しい Test クラスが元のプロジェクトに追加された場合、それらを自動的に取得しないことです。新しい Test クラスが元のプロジェクトに追加されるのを監視する必要があります。これはこれまでのところ私の最良の選択肢ですが、理想的ではありません。

  • 私が考えることができる他の唯一のオプションは、とにかく悪いテストを実行し、失敗を無視することです. ただし、これらのテストは実行に時間がかかる (そして失敗する!) ため、まったく実行しないことをお勧めします。さらに、特定のテスト メソッドの失敗を無視するように Ant タスクに指示する方法がわかりません (繰り返しますが、個々のテスト クラスに対してそれを行う方法はわかりますが、メソッドについてはわかりません)。

4

7 に答える 7

4

元のテストにまったく触れることができない場合、いくつかの深刻な制限が生じることになります。あなたのオーバーライドは最善の策のように聞こえますが、いくつかの変更があります。

特にスーパー クラスを除外して Ant テストをビルドし、知らない追加のクラスが実行されるようにします。

@Rule アノテーション (JUnit 4.7 の新機能) を使用して、特定のメソッドをオーバーライドするのではなく、どのテストが実行されているかを知り、(空の Statement 実装を返すことによって) 中止することができるため、テストを回避するかどうかをより柔軟に知ることができます。 . このメソッドの唯一の問題は、このメソッドを使用して実行中の @Before メソッドを停止できないことです。これは遅くなる可能性があります。それが問題である場合 (そして実際にテストに触れることができない場合)、オーバーライドされたメソッドの @Ignore が私が考えることができる唯一のものです。

ただし、これらのテストに触れることができれば、いくつかの追加オプションが開かれます。

クラスに @RunWith タグを指定することで、カスタム ランナーでそれらを実行できます。このランナーは、そのプロジェクトの標準ランナー (JUnit4.class) に実行を渡すだけですが、プロジェクトでは (システム プロパティまたはその他のメカニズムを介して) テスト名を検査し、テストを実行しません。これには、邪魔にならないという利点がありますが、実装が最も困難です (ランナーは毛むくじゃらの獣であり、@Rule の目標の 1 つは、ランナーを作成する必要性をほとんどなくすことでした)。

もう 1 つは、そのテストを実行する必要がある場合に true になる構成設定をチェックする、テストで assumeThat ステートメントを作成することです。それには、実際にはテストに直接注入することが含まれます。これは、リモートで「別のプロジェクト」とラベル付けされたものでは、契約を破る可能性が最も高いです。

于 2009-09-02T17:19:13.773 に答える
3

今は役に立ちませんが、TestNGはこの種の機能をサポートしています。

于 2009-09-02T17:51:39.543 に答える
2

OK、これはかなり重い解決策ですが、ばかげているように聞こえても、私に物を投げつけないでください。

Junit4 のコアは、org.junit.runner.Runnerクラスとそのさまざまなサブクラスです。最も重要なのはorg.junit.runners.Suite. これらのランナーは、@Test や @Ignore などを使用して、特定のテスト クラスのテストを決定します。

ランナーのカスタム実装を作成するのは非常に簡単で、通常はテスト クラスのアノテーションを使用してそれらを接続し@RunWithますが、明らかにそれは選択肢ではありません。

ただし、理論的には、おそらく標準の Ant Junit タスクに基づいて、独自の Ant タスクを作成できます。これは、カスタム テスト ランナーを取得して直接使用し、各テスト クラスを順番に渡します。ランナーの実装では、無視するテスト メソッドを指定する外部構成ファイルを使用できます。

それは非常に大変な作業であり、それがどのように機能するかを知るには、先史時代の Ant Junit コードベースを掘り下げるのに時間を費やす必要があります。ただし、時間への投資はそれだけの価値があるかもしれません。

Junit Ant タスクがテスト ランナーを指定するメカニズムを提供していないのは残念ですが、それは理想的です。

于 2009-09-02T17:20:07.640 に答える
1

述べられた制約であなたが望むものを達成するために私が考えることができる可能性は、バイトコードの変更を使用することです。無視するクラスとメソッドのリストを別のファイルに保持し、ロード時にテスト クラスのバイトコードにパッチを適用して、このメソッドを完全に削除することができます。

私が間違っていなければ、JUnit はリフレクションを使用して、実行するテスト メソッドを見つけます。メソッドの名前変更操作により、JUnit が検出する前にこれらのメソッドを削除できます。または、操作を実行せずにすぐに戻るようにメソッドを変更することもできます。

BCELのようなライブラリを使用して、ロード時にクラスを変更できます。

于 2009-09-02T17:21:09.293 に答える
1

テストのサブセットのみを実行したい場合、そのクラスには複数の責任があり、リファクタリングする必要があるように思えます。または、テスト クラスを分割して、元のプロジェクトにすべてのテストを含めることができますが、1 つまたは複数のクラス (テストのいくつかは実際には統合テストであり、データベースまたはネットワークに触れていると思います) を使用し、クラスを除外することができます ( es) あなたは望んでいませんでした。

それができない場合は、オーバーライドするオプションがおそらく最適です。そのクラスを拡張して Ant 除外リストに追加するいくつかのメソッドを無視する必要があるときはいつでもプロセスを実行します。そうすれば、パスできないものを除外でき、ビルドを変更せずにすべての新しいテスト (オーバーライドしなかったメソッドと新しいテスト クラス) を引き続き取得できます。

于 2009-09-02T18:18:24.323 に答える
0

不要なテストが特定のクラス/パッケージにある場合は、Ant でファイルセットの除外を使用して、インポート中にそれらを除外できます。

于 2009-09-02T17:05:31.943 に答える