Как запустить тест Gradle, когда все тесты UP-TO-DATE?

У меня установлен мой скрипт. Когда я выполняю сборку 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 build... Я хочу, чтобы иметь возможность сбросить только те тесты, а не строить весь проект: как мне это сделать?

Ответ 1

Один из вариантов будет использовать флаг --rerun-tasks в командной строке. Это приведет к повторному запуску всей тестовой задачи и всех задач, от которых она зависит.

Если вы заинтересованы только в повторном тестировании, тогда еще один вариант - сделать градулы чистыми результаты тестов перед выполнением тестов. Это можно сделать с cleanTest задачи cleanTest.

В некотором роде - плагин Java определяет чистые задачи для каждой из других задач. Согласно документации:

cleanTaskName - Удаляет файлы, созданные указанной задачей. cleanJar удалит JAR файл, созданный задачей jar, и cleanTest удалит результаты теста, созданные тестовой задачей.

Таким образом, все, что вам нужно для повторного запуска ваших тестов, также должно запустить задачу cleanTest, то есть:
gradle cleanTest test

Ответ 2

Другой вариант - добавить в свой файл build.gradle следующее:

test.outputs.upToDateWhen {false}

Ответ 4

Вот решение, использующее файл 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

Ответ 5

Это было недавно темой в блоге Gradle Хватит перезапускать свои тесты. автор показывает пример использования outputs.upToDateWhen { false } и объясняет, почему это не так:

Это на самом деле не приводит к повторному запуску

Автор этого фрагмента, вероятно, хотел сказать: "Всегда перезапускать мои тесты". Это не то, что делает этот фрагмент, хотя. Это только помечает задачу как устаревшую, заставляя Gradle воссоздать вывод. Но вот в чем дело, если кеш сборки включен, Gradle не нужно запускать задачу, чтобы воссоздать вывод. Он найдет запись в кеше и распакует результат в выходной каталог test.

То же самое относится и к этому фрагменту:

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()
}

Я рекомендую прочитать весь пост в блоге.

Ответ 6

Кроме того, необходимость добавления --rerun-tasks действительно избыточна. Никогда не бывает. Создайте --no-rerun-tasks --rerun-tasks и сделайте --rerun-tasks default, когда cleanTask

Ответ 7

--rerun-tasks работает, но неэффективно, так как перезапускает все задачи.

cleanTest само по себе может быть недостаточно из-за кеша сборки.

Итак, лучший способ сделать это:

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

Ответ 8

Я думаю, что это правильный вопрос, учитывая, что в Gradle можно запустить этот командный test, и происходит то, что ничего не происходит!

Но я бы поставил под сомнение необходимость когда-либо делать это, как сказала Джолта в своем комментарии: если код не изменился, почему вам нужно перепроверить? Если у вас есть сомнения в отношении стороннего ввода, я бы сказал, что вам нужно это сделать в коде приложения. Если вы беспокоитесь о том, что ваш код может быть "flaky", то есть он может проходить все тесты в первый раз, но не через секунду (или 100-й раз), вам не нужно думать о том, почему у вас есть эти сомнения и адресовать их?

Лично я думаю, что это (очень незначительная) ошибка дизайна в Gradle: если все полностью обновлено, а не "BUILD SUCCESSFUL", оно должно сказать "NO CHANGE SINCE LAST SUCCESSFUL BUILD: NOTHING DONE".