모든 테스트가 최신 상태 일 때 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

10
@Jolta 내 코드의 일부 테스트는 3 자 입력과 관련이 있습니다. 코드에 버그를 넣지 않았는지 확인하고 3 자 입력에 변경 사항이 있는지 확인하기 위해 테스트를 실행하고 있습니다 내가 얻는거야
USer22999299

4
엄청나게 미안하지만 실제로 이것이 이것에 대한 올바른 생각이라고 생각하지 않습니다 : 가변 3 자 입력이있는 경우 어떤 식 으로든 입력을 조롱하기 위해 이것을 처리하는 올바른 방법이 아니십니까? 테스트는 실제로 작성중인 코드를 테스트하는 것입니다. 당신이 받아 들일 수없는 제삼자 의견에 의존한다면 당신은 위양성을 얻을 위험이 분명하지 않습니까? 앱 코드의 일부로 문제 입력을 수용하는 전략이 아니어야합니까?
마이크 설치류

9
@mikerodent는 타사 온라인 서비스에 대한 코드 테스트를 고려합니다. 배치 된 수정 사항에 최대한 빨리 응답 할 수 있도록 서비스 API에서 가능한 변경 사항을 모니터하려고합니다. CI 테스트가 그렇게하는 좋은 방법이 아닙니까? 모의를 사용하면 자신의 코드에 회귀가 없다는 것을 알 수 있지만 종속성에 여전히 변경 사항이있을 수 있습니다. 실제 서비스를 사용하면 제품이 현재 환경에서 실제로 예상되는 작업을 수행 할 수 있음을 나타냅니다.
Elist

5
이것은 또한 테스트 포인트가 다른 코드 비트와 코드의 통합을 검증하는 통합 테스팅 관점에서도 유효합니다. 의존성에 조롱하는 것이 적절하지 않은 경우
1800 INFORMATION

답변:


171

하나의 옵션은 명령 행--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기능 테스트를 실행하기 위해 만든 작업 에이 기술을 사용했습니다 .
pharsicle

4
이것은 원하는 작업에만 적용되므로 허용되는 답변보다 훨씬 나은 방법입니다. 은 upToDateWhen같은 시스템 특성, 환경 변수, 프로젝트 속성 등으로 어떤 '코드 중심'방식으로 사용할 수 있습니다
mkobit

1
답변 stackoverflow.com/a/52484259/340175에서 언급 했듯이 유용한 블로그 게시물 blog.gradle.org/stop-rerunning-tests 에이 접근 방식이 일반적인 접근 방식으로 권장되지 않는 이유가 설명되어 있습니다. 그러나 나는 그것이 유용 할 수 있고 질문이 묻는 것을 달성한다는 데 동의합니다.
JulianHarty

그렇습니다.이 Gradle은 버전 2.11에 작성되어 방금 사용할 수 있었지만 오늘날까지 연마 된 거친 가장자리가 많았습니다.
František Hartman

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은 출력이 정리 된 후 빌드 캐시에서 테스트 결과의 압축을 풀므로 아무것도 다시 실행되지 않습니다. 요컨대,이 스 니펫은 비용이 많이 드는 no-op를 생성합니다.

"알겠습니다. 캐시도 비활성화하겠습니다"라고 생각하면 왜 안되는지 알려 드리겠습니다.

그런 다음 저자는 왜 일부 테스트를 다시 실행하는 것이 시간 낭비인지 설명합니다.

대부분의 테스트는 결정 론적이어야합니다. 즉, 동일한 입력이 주어지면 동일한 결과를 가져와야합니다.

코드가 변경되지 않은 테스트를 다시 실행하려는 경우 입력으로 모델링해야합니다. 다음은 블로그 게시물에서 입력을 추가하여 작업을 최신 확인 중에 사용하도록 표시하는 예제입니다.

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

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

전체 블로그 게시물을 읽는 것이 좋습니다.


8
이것은 당신이 이야기하는 특정 유스 케이스에 좋지만 들리지만 라이브 외부 웹 서비스에 대해 배치 후 테스트를 작성 중이며 junit과 gradle을 사용하여이를 수행하고 있습니다. 테스트중인 코드는 저장소에 존재 하지 않으며 실제로 코드 자체가 아닌 실제 프로덕션 시스템을 테스트하기 때문에 실제로 '응용 프로그램 코드' 없습니다. 답변 주셔서 감사합니다, 이것은 매우 유용합니다! 코드 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 was user2321368

8

--rerun-tasks 작동하지만 모든 작업을 다시 실행하므로 비효율적입니다.

cleanTest 캐시 자체로 인해 자체로는 충분하지 않을 수 있습니다.

따라서이를 수행하는 가장 좋은 방법은 다음과 같습니다.

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

0

또한 추가해야하는 --rerun-tasks것은 실제로 중복됩니다. 절대 일어나지 않습니다. 다음 --no-rerun-tasks을 만들 --rerun-tasks때 기본값을 지정하십시오.cleanTask



-4

Gradle 에서이 명령을 실행할 수 있다는 점을 감안할 때 이것이 유효한 질문이라고 생각 test하며 아무 일도 일어나지 않습니다!

그러나 Jolta가 자신의 의견에서 말한 것처럼 코드를 변경하지 않은 경우 왜 다시 테스트해야합니까? 타사 입력에 대해 의문이 있으면 앱 코드에서이를 충족시켜야한다고 말하고 싶습니다. 코드가 "불완전"할 수 있다는 우려가있는 경우, 즉 모든 테스트를 처음에는 통과하지만 두 번째 (또는 100 회)에는 통과 할 수없는 경우, 이러한 의심이있는 이유에 대해 생각할 필요가 없습니까?

개인적으로 이것은 Gradle에서 (사소한) 디자인 결함이라고 생각합니다. "성공적으로 성공"하지 않고 모든 것이 최신 상태라면 "최종 성공한 빌드 이후 변경 사항이 없습니다."라고 표시해야합니다.


3
"이러한 의심이있는 이유에 대해 생각할 필요가 없으십니까?" 너무 미쳤어?
mhsmith

1
@ mikerodent 나는 당신의 요점에 부분적으로 동의합니다. 일반적으로 간단한 화이트 박스 단위 테스트 인 "쉬운"사례가 있으며 코드 변경이 전혀 없다는 것은 다시 테스트 할 필요가 없습니다. 의존성이있는 테스트를 생각해보십시오. "아, 그래, 도커는 달리지 않았다." 빌드가 아닌 종속성 ( "제공됨")을 설정하는 인프라 (및 개발자) 테스트가 있습니다. 이 경우 항상 다시 실행할 수 있기를 원합니다.
dbalakirev

@dbalakirev 예, 이것은 나에게 발생했습니다 ...하지만 Docker와 같은 이러한 종속성의 역할을 조롱해서는 안됩니다 ...? 당신이 만약 내 말은 하지 않는 그 일을 당신은 미래의 문제를 저장하지 않습니다? 나는 100 % 확신한다고 말하지는 않지만, 내가 생각하는 것은 당신의 테스트가 세상보다 의심 할 여지없이 모든베이스를 포함해야한다는 것입니다.
마이크 설치류

당신은 당신에게 실패하면 코드가 변경되지 않은 경우에도 다시 실행하고 싶다는 의존성 (docker)을 가지고 있음을 모의 할 수 있습니다. 나는이 생각이 단위 테스트 나 테스트를위한 것이 아니라는 것을 강조하고 싶습니다 .
dbalakirev

2
__ 코드가 변경되지 않은 경우 왜 다시 테스트해야합니까? __ 통합 테스트에 대해 들어 보셨습니까?
Bogdan Mart
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.