これに対する解決策は、私が思っていたよりも小さくてトリッキーでした。Gradle はカスタム テスト ランナーを使用し、filter
メソッドを正しく呼び出していました。ただし、私のランナーは、Javaassist 拡張用の独自のクラスローダーを介してすべてのテスト クラスをリロードします。
これにより、SlowTest
注釈が Gradle クラスローダーを介して読み込まれるという問題が発生しましたが、カスタム ランナーに渡されると、ランナーはクラスにその注釈が付けられているかどうかをチェックしました。SlowTest
2 つの異なるクラスローダーを介してロードされたアノテーションの同等性が異なるため、このチェックは正しく解決されませんでした。
--
すでに調査済みなので、ここでは省略します。Gradle と (不可解な) JUnit ソースを何日も掘り下げた結果、得られたものは次のとおりです。
Gradle は、テストの分類を除いて、高度な JUnit 機能をまったく処理しません。include-categories または exclude-categories 条件で Gradle タスクを作成すると、CategoryFilter が作成されます。ご存じない場合は、 aFilter
は、テストまたはテスト メソッドを除外する必要があるかどうかを判断するために JUnit がテスト ランナーに与えるものです。テスト ランナーはFilterable
インターフェイスを実装する必要があります。
JUnit には複数のランナーが付属しており、これCategories
はそのうちの 1 つにすぎません。と呼ばれるテスト ランナーのファミリを拡張しSuite
ます。これらのスイート ベースのランナーは、テストの「スイート」を実行するように設計されています。一連のテストは、アノテーション イントロスペクションによって、スイート内でテストを明示的に定義することによって、または一連のテストを構築する他の方法によって構築できます。
ランナーの場合Categories
、JUnit には独自のものCategoryFilter
がありますが、Gradle はそれを使用せず、独自の を使用しCategoryFilter
ます。どちらも多かれ少なかれ同じ機能を提供し、JUnit フィルターであるため、 を実装する任意のスイートで使用できますFilterable
。
JUnit テストの実行を担当する Gradle の実際のクラスは と呼ばれJUnitTestClassExecuter
ます。コマンド ライン オプションを解析すると、ランナーをテストに使用する必要があるかどうかを確認するよう JUnit に要求します。このメソッドは、ここに示されているように、すべてのテストに対して呼び出されます。
あとは JUnit 次第です。Gradle はRunNotifier
、テスト結果を表す標準 XML ファイルを生成するためのカスタムを作成しました。
誰かがこれを役に立ち、数え切れないほどのデバッグ時間を節約してくれることを願っています。
TLDR: Gradle では任意のランナーを使用できます。Gradle には、ランナーに関する詳細はありません。出走者を決めたのはJUnitです。テストに使用されるランナーを知りたい場合は、 を呼び出してこれをデバッグできます
Request.aClass(testClass).getRunner()
。これをコードベースのどこかにハッキングして、コンソールに出力します。(デバッガーを Gradle に接続することにあまり成功しませんでした。)