すべてのテストが最新の状態でGradleテストを実行するにはどうすればよいですか?


130

成績スクリプトを設定しました。Gradleビルドを実行すると、すべてが機能し、jUnitテストが実行されます。

その後、Gradleテストを実行すると、次のようになります。

C:\Users\..\..\Project>gradle test
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE

を実行するとgradle clean、もちろんGradleビルドが機能します...プロジェクト全体をビルドするのではなく、テストのみをリセットできるようにしたいのですが、どうすればよいですか?


3
これは、与えられた情報に基づいて、不要と思われます。アプリケーションコードもテストコードも変更されていない場合、テストを再実行する必要があるのはなぜですか。
Jolta、2015

10
@Joltaコード内のテストの一部はサードパーティの入力に関連しています。テストを実行して、コード内にバグがないことを確認するだけでなく、サードパーティの入力に何か変更があるかどうかを確認しています私が得ていること
USer22999299

4
ありがたいことに申し訳ありませんが、これはこれについて正しい考え方ではないと私は思います:可変の3者入力がある場合、これを処理してこれらの入力を何らかの方法で模倣する正しい方法ではありませんか?テストとは、実際には、作成しているコードをテストすることです。受け入れられないように3者の入力に依存している場合、誤検知が発生するというかなり明白な危険にさらされていませんか?アプリのコードの一部として問題のある入力に対応するのが戦略ではありませんか?
マイクげっ歯類

9
@mikerodentは、サードパーティのオンラインサービスに対してコードをテストすることを検討してください。デプロイされた修正でできるだけ早く応答できるように、サービスAPIで起こり得る変更を監視する必要があります。CIテストはそれを行う良い方法ではありませんか?モックを使用すると、独自のコードにリグレッションがないことだけがわかりますが、依存関係はまだ変更されている可能性があります。実際のサービスを使用すると、製品が現在の環境で実際に期待される操作を実行できることがわかります。
Elist

5
これはテストのポイントは、依存関係にモックすることは適切ではないことになる場合には、コードの他のビットを使用して、コードの統合を検証することですビューの統合テストの点からも有効である
1800 INFORMATION

回答:


171

1つのオプションは--rerun-tasksコマンドラインでフラグを使用することです。これにより、すべてのテストタスクとそれに依存するすべてのタスクが再実行されます。

テストの再実行のみに関心がある場合は、テストを実行する前に、gradleでテスト結果をクリーンアップすることもできます。これは、cleanTestタスクを使用して行うことができます。

背景-Javaプラグインは、他の各タスクに対してクリーンなタスクを定義します。ドキュメントによると:

cleanTaskName-指定されたタスクによって作成されたファイルを削除します。cleanJarはjarタスクによって作成されたJARファイルを削除し、cleanTestはテストタスクによって作成されたテスト結果を削除します。

したがって、テストを再実行するために必要なのは、cleanTestタスクも実行することだけです。つまり、
gradle cleanTest test


3
gradle cleanTest testテストを再実行せず、出力をクリーンアップしますが、testタスクはキャッシュからテスト結果を取得します-github.com/gradle/gradle/issues/9153を
dan.mはuser2321368

3
上記のコメントは正しいです。ただし、を使用すると--no-build-cache、期待どおりに機能しますgradle cleanTest test --no-build-cache
vRallev

51

その他のオプションは、build.gradleに以下を追加することです。

test.outputs.upToDateWhen {false}

1
funcTest機能テストを実行するために作成したタスクにこの手法を使用しました。
ファルシクル

4
これは、望ましいタスクにのみ適用されるため、受け入れられた回答よりもはるかに優れたアプローチです。upToDateWhenなどのシステムプロパティ、環境変数、プロジェクトのプロパティ、など任意の「コード・ドリブン」な方法で使用することができます
mkobit

1
回答stackoverflow.com/a/52484259/340175が言及しているように、このアプローチが一般的なアプローチとして推奨されない理由を説明する有用なブログ投稿blog.gradle.org/stop-rerunning-testsがあります。しかし、私はそれが有用であるかもしれず、質問が尋ねるものを達成することに同意します。
JulianHarty

はい、これは日付付きの回答です。私がこのGradleを書いたときのバージョンは2.11で、使い始めたばかりですが、まだ多くの粗いエッジがあり、今日は洗練されています。
Františekハートマン

1
素晴らしい答え!!! パラメータを使用して渡されました:gradle test -Prerun-tests。build.gradleのコード:if(project.hasProperty("rerun-tests")) { test.outputs.upToDateWhen {false} }
AlikElzin-kilaka


17

これは最近、Gradleのブログ投稿「テストの再実行を停止する」のトピックでした。著者は、使用例を示しoutputs.upToDateWhen { false }、それは間違っている理由を説明します。

これは実際には再実行を強制しません

このスニペットの作成者がおそらく言いたかったのは、「常にテストを再実行する」です。しかし、このスニペットはそうではありません。これは、タスクに古いマークを付けるだけで、Gradleに出力を再作成させます。しかし、ビルドキャッシュが有効になっている場合、Gradleは出力を再作成するためにタスクを実行する必要はありません。キャッシュ内のエントリを見つけ、結果をテストの出力ディレクトリに解凍します。

このスニペットについても同様です。

test.dependsOn cleanTest

Gradleは、出力がクリーンアップされた後にビルドキャッシュからテスト結果をアンパックするため、何も再実行されません。要するに、これらのスニペットは非常に高価なノーオペレーションを作成しています。

「さあ、私もキャッシュを非アクティブ化します」と考えているなら、そうすべきでない理由を教えてください。

その後、著者はさらに、いくつかのテストを再実行することが時間の無駄である理由を説明します。

テストの大部分は確定的である必要があります。つまり、同じ入力が与えられた場合、同じ結果が得られるはずです。

コードが変更されていない場所でテストを再実行したい場合は、それらを入力としてモデル化する必要があります。以下は、ブログの投稿の例で、入力を追加してタスクを最新のチェック中に使用できるようにする例を示しています。

task randomizedTest(type: Test) {
  systemProperty "random.testing.seed", new Random().nextInt()
}

task systemIntegrationTest(type: Test) {
  inputs.property "integration.date", LocalDate.now()
}

ブログ投稿全体を読むことをお勧めします。


8
これは、あなたが話している特定のユースケースに最適に聞こえますが、私はライブの外部Webサービスに対するデプロイメント後のテストを書いていて、たまたまjunitとgradleを使用してこれを実現しています。テスト中のコードはリポジトリに存在せず、実際に「アプリケーションコード」はありません。これは、コード自体ではなく、実際の運用システムを実際にテストしているためです。答えてくれてありがとう、これはとても便利です!コードグラドルが変更を認識していない場合でも毎回テストを再実行する必要がある追加のユースケースがあることを指摘したかっただけです
Brandon

11

コマンドラインを変更したくない場合に備えて、「build.gradle」ファイルを使用した解決策を次に示します。

test {
    dependsOn 'cleanTest'
    //Your previous task details (if any)
}

そして、これが出力です。以前の出力からの2つの変更に注意してください。

1)新しい「cleanTest」タスクが出力に表示されます。

2) 'test'は常にクリーンアップされるため(つまり、 'UP-TO-DATE'ではありません)、毎回実行されます。

$ gradle build
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:findMainClass
:jar
:bootRepackage
:assemble
:cleanTest
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test
:check
:build

1
実行するcleanTest前にすると、testテストを再実行しないであろう、それは彼らの出力をきれいますが、テスト・タスクがまだキャッシュからテスト結果を取得します- github.com/gradle/gradle/issues/9153を参照してください
dan.mはuser2321368た

8

--rerun-tasks 動作しますが、すべてのタスクを再実行するため、非効率的です。

cleanTest ビルドキャッシュが原因で、それ自体では不十分な場合があります。

したがって、これを達成する最良の方法は次のとおりです。

./gradlew --no-build-cache cleanTest test

0

また、追加する必要があること--rerun-tasksは本当に冗長です。決して起こらない。を作成し--no-rerun-tasks--rerun-tasksデフォルトにするcleanTask



-4

Gradle testではこのコマンドを実行することが可能であり、何も起こらないということを考えると、これは有効な質問だと思います。

しかし、ジョルタがコメントで言ったように、私はこれを行う必要性を疑問視します:コードが変更されていない場合、なぜ再テストが必要なのですか?サードパーティの入力について疑問がある場合は、アプリのコードでこれに対応する必要があると思います。コードが「不安定」になる可能性がある、つまりすべてのテストに最初は合格できるが2回目(または100回目)は合格できないと心配している場合は、これらの疑問がある理由を考えて対処する必要はありませんか。

個人的には、これはGradleの(非常にマイナーな)設計上の欠陥だと思います。すべてが完全に最新である場合、「BUILD SUCCESSFUL」ではなく、「NO CHANGE SINCE LAST SUCCESSFUL BUILD:NOTHING DONE」と表示されます。


3
「なぜこれらの疑問があるのか​​を考えて対処する必要はありませんか?」クレイジーですか?
mhsmith

1
@mikerodent私はあなたの主張に部分的に同意します。「簡単な」ケースがあり、通常は単純なホワイトボックスユニットテストです。コードの変更がなければ、再テストする必要はありません。ただし、依存関係のあるテストについて考えてみてください。「そうそう、ドッカーは動いていないなど」ビルドではなく依存関係( "提供"されている)をセットアップするのはインフラストラクチャ(および開発者)であるテストがあります。これらのケースでは、常に再実行できるようにしたいと思っています。
dbalakirev 2017

@dbalakirevはい、これは私に起こりました...しかし、Dockerなどのこれらの依存関係の役割を模倣することはできませんか?つまり、あなたがそうしていなければ、将来の問題を蓄えていませんか?100%確実だと言っているわけではありませんが、私が言っていることは、私たちのテストは間違いなく私たちのテストよりも理想的であり、すべてのベースをカバーする必要があるということです。
マイクげっ歯類

あなたはイエスをあざけるかもしれませんが、依存関係(docker)があり、失敗した場合、コードが変更されていなくても再実行する必要があることを意味します。この考えは、単体テストや依存関係を避けようとするテスト、または少なくともテストフレームワークを使用してそれらを模擬するテストではないことを強調したいと思いますが、実際に「提供」されている場合はそうします。
dbalakirev 2017

2
__コードが変更されていない場合、なぜ再テストが必要なのですか?__統合テストについて聞いたことがありますか?
ボグダンマート
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.