8

と呼ばれる基本テストクラスを拡張するJUnitテストがたくさんありBaseTestますAssert。私のテストのいくつかには@Category(SlowTests.class)注釈があります。

BaseTestのクラスには、次の注釈が付けられています@RunWith(MyJUnitRunner.class)

のみ実行することが期待される Gradle タスクをセットアップしましたSlowTests。これが私のGradleタスクです:

task integrationTests(type: Test) {
    minHeapSize = "768m"
    maxHeapSize = "1024m"
    testLogging {
        events "passed", "skipped", "failed"
        outputs.upToDateWhen {false}
    }
    reports.junitXml.destination = "$buildDir/test-result"
    useJUnit {
        includeCategories 'testutils.SlowTests'
    }
}

タスクを実行すると、テストが実行されません。私はこの問題が のカスタム ランナーMyJUnitRunnerに関連していることを突き止めましたBaseTest。を使用しているときにカスタム ランナーを使用できるように、Gradle またはテスト構造をセットアップするにはどうすればよいですかSuite

4

1 に答える 1

6

これに対する解決策は、私が思っていたよりも小さくてトリッキーでした。Gradle はカスタム テスト ランナーを使用し、filterメソッドを正しく呼び出していました。ただし、私のランナーは、Javaassist 拡張用の独自のクラスローダーを介してすべてのテスト クラスをリロードします。

これにより、SlowTest注釈が Gradle クラスローダーを介して読み込まれるという問題が発生しましたが、カスタム ランナーに渡されると、ランナーはクラスにその注釈が付けられているかどうかをチェックしました。SlowTest2 つの異なるクラスローダーを介してロードされたアノテーションの同等性が異なるため、このチェックは正しく解決されませんでした。

--

すでに調査済みなので、ここでは省略します。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 に接続することにあまり成功しませんでした。)

于 2016-10-31T15:34:07.710 に答える