Gradle에 새 소스 세트를 어떻게 추가합니까?


99

Gradle 빌드 (버전 1.0)에 통합 테스트를 추가하고 싶습니다. webapp을 localhost에 배포해야하기 때문에 내 일반 테스트와 별도로 실행해야합니다 (그 웹앱을 테스트합니다). 테스트는 내 기본 소스 세트에 정의 된 클래스를 사용할 수 있어야합니다. 어떻게해야합니까?

답변:


114

이것은 내가 알아내는 데 시간이 걸리고 온라인 리소스가 좋지 않았습니다. 그래서 내 솔루션을 문서화하고 싶었습니다.

이것은 기본 및 테스트 소스 세트 외에도 intTest 소스 세트가있는 간단한 gradle 빌드 스크립트입니다.

apply plugin: "java"

sourceSets {
    // Note that just declaring this sourceset creates two configurations.
    intTest {
        java {
            compileClasspath += main.output
            runtimeClasspath += main.output
        }
    }
}

configurations {
    intTestCompile.extendsFrom testCompile
    intTestRuntime.extendsFrom testRuntime
}

task intTest(type:Test){
    description = "Run integration tests (located in src/intTest/...)."
    testClassesDir = project.sourceSets.intTest.output.classesDir
    classpath = project.sourceSets.intTest.runtimeClasspath
}

7
여전히 통합 테스트 작업을 선언하고 구성해야합니다. 문서 측면 java/withIntegrationTests에서 전체 Gradle 배포판에 샘플이 있습니다.
Peter Niederwieser

감사합니다 @PeterNiederwieser 샘플 빌드 스크립트를 수정했습니다.
Spina

2
나도 이렇게하려고
Igor Popov

@PeterNiederwieser 감사합니다-연결해 주시겠습니까? 또한이 정확한 상황이 문서에서 심각하게 부족하다는 것을 발견했습니다. 새 sourceSet을 정의하는 것은 모두 훌륭하고 좋지만 실제 컴파일, jar, 테스트 및 대상이 아닌 대상에 "연결"하는 것에 대한 정보는 없습니다. 해당 sourceSet에서 항아리에 넣거나 새 항아리 만들기).
stolsvik 2014 년

6 행에서 IntelliJ를 사용할 때 "Cannot resolve symbol 'java'"가 표시됩니다. 왜 그런지 생각해?
Snekse 2014

33

을 사용하지 않고이를 달성 한 방법은 다음과 같습니다 configurations{ }.

apply plugin: 'java'

sourceCompatibility = JavaVersion.VERSION_1_6

sourceSets {
    integrationTest {
        java {
            srcDir 'src/integrationtest/java'
        }
        resources {
            srcDir 'src/integrationtest/resources'
        }
        compileClasspath += sourceSets.main.runtimeClasspath
    }
}

task integrationTest(type: Test) {
    description = "Runs Integration Tests"
    testClassesDir = sourceSets.integrationTest.output.classesDir
    classpath += sourceSets.integrationTest.runtimeClasspath
}

다음을 사용하여 테스트 : Gradle 1.4 및 Gradle 1.6


2
공유해 주셔서 감사합니다! 대체 구현을 보는 것이 좋습니다.
Spina

1
하면서 java { srcDir 'src/integrationtest/java' } resources { srcDir 'src/integrationtest/resources' }그냥 redeclares는 이후 관련이 없습니다 src/<sourceSetName>/...src/integrationtest/...여기 : 낮은 t에 자본 T 변경
childno͡.de

이 접근 방식에주의하십시오. compileClasspath += sourceSets.main.runtimeClasspath두 세트의 파일을 결합합니다. 종속성에 대한 일반적인 충돌 해결 방법은 없습니다. 동일한 라이브러리의 두 가지 버전으로 끝날 수 있습니다. 구성을 확장하면 도움이됩니다.
chalimartines

20

이것은 한때 2016 년 Gradle 2.x / 3.x 용으로 작성되었으며 훨씬 구식입니다 !! Gradle 4 이상에서 문서화 된 솔루션을 살펴보십시오 .


두 가지 이전 답변을 모두 요약하려면 (두 세계 모두에서 최고 및 최소 실행 가능) :

먼저 몇 가지 따뜻한 말 :

  1. 먼저 다음을 정의해야합니다 sourceSet.

    sourceSets {
        integrationTest
    }
    
  2. 우리가 확장 옆 sourceSet에서 test, 우리는 사용 그에 대한 test.runtimeClasspath(모든 dependenciess를 포함 testtest파생에 대한 클래스 경로로 자리) sourceSet:

    sourceSets {
        integrationTest {
            compileClasspath += sourceSets.test.runtimeClasspath
            runtimeClasspath += sourceSets.test.runtimeClasspath // ***)
        }
    }
    
    • 참고 ) 어떻게 든이 재 선언 / 확장 sourceSets.integrationTest.runtimeClasspath이 필요하지만 runtimeClasspath항상 확장 되므로 관련이 없어야 output + runtimeSourceSet합니다.
  3. 통합 테스트를 실행하기위한 전용 작업을 정의합니다.

    task integrationTest(type: Test) {
    }
    
  4. integrationTest테스트 클래스 및 클래스 경로 사용을 구성하십시오 . java플러그인 의 기본값 은test sourceSet

    task integrationTest(type: Test) {
        testClassesDir = sourceSets.integrationTest.output.classesDir
        classpath = sourceSets.integrationTest.runtimeClasspath
    }
    
  5. (선택 사항) 테스트 후 자동 실행

    integrationTest.dependsOn 테스트
    

  6. (선택 사항) 종속성 추가 check(따라서 항상 실행 build되거나 실행될 때 check실행 됨)

    tasks.check.dependsOn(tasks.integrationTest)
  7. (선택 사항) 에 java, resources를 추가 sourceSet하여 자동 감지를 지원하고 IDE에서 이러한 "부분"을 만듭니다. 즉, IntelliJ IDEA는 sourceSet존재하지 않는 경우 각 세트에 대한 Java 및 리소스 디렉토리 를 자동으로 만듭니다 .

    sourceSets {
         integrationTest {
             java
             resources
         }
    }
    

tl; dr

apply plugin: 'java'

// apply the runtimeClasspath from "test" sourceSet to the new one
// to include any needed assets: test, main, test-dependencies and main-dependencies
sourceSets {
    integrationTest {
        // not necessary but nice for IDEa's
        java
        resources

        compileClasspath += sourceSets.test.runtimeClasspath
        // somehow this redeclaration is needed, but should be irrelevant
        // since runtimeClasspath always expands compileClasspath
        runtimeClasspath += sourceSets.test.runtimeClasspath
    }
}

// define custom test task for running integration tests
task integrationTest(type: Test) {
    testClassesDir = sourceSets.integrationTest.output.classesDir
    classpath = sourceSets.integrationTest.runtimeClasspath
}
tasks.integrationTest.dependsOn(tasks.test)

참조:

안타깝게도 github.com/gradle/gradle/subprojects/docs/src/samples/java/customizedLayout/build.gradle 또는 … / gradle /… / withIntegrationTests / build.gradle 의 예제 코드는 이를 처리하지 않거나 다른 / 더 복잡합니다 / 어쨌든 더 명확한 해결책은 없습니다!


1
(!) 구성이나 출력없이 sourceSet 향상을 한 번만 사용하면 프로젝트를 처음 연 후 아이디어에 오류가 발생합니다. (여기서는 테스트) 빌드 의존성 (여기 : integrationTest) 새로운 "모듈"에 대한 처음에 사용할 수 없습니다compileTestJava
childno͡.de

2
classesDirclassesDirsgradle 5 에서 마이그레이션되었습니다
deFreitas

힌트 @deFreitas 주셔서 감사합니다, 나는 구식으로 답을 표시
childno͡.de


7

사용하는 경우

IntelliJ가 사용자 정의 소스 세트를 테스트 소스 루트로 인식하도록하려면 :

plugin {
    idea
}

idea {
    module {
        testSourceDirs = testSourceDirs + sourceSets["intTest"].allJava.srcDirs
        testResourceDirs = testResourceDirs + sourceSets["intTest"].resources.srcDirs
    }
}

2

Gradle 4.0에서 저에게 적합한 것은 다음과 같습니다.

sourceSets {
  integrationTest {
    compileClasspath += sourceSets.test.compileClasspath
    runtimeClasspath += sourceSets.test.runtimeClasspath
  }
}

task integrationTest(type: Test) {
  description = "Runs the integration tests."
  group = 'verification'
  testClassesDirs = sourceSets.integrationTest.output.classesDirs
  classpath = sourceSets.integrationTest.runtimeClasspath
}

버전 4.0부터 Gradle은 이제 소스 세트의 각 언어에 대해 별도의 클래스 디렉토리를 사용합니다. 따라서 빌드 스크립트가를 사용 sourceSets.integrationTest.output.classesDir하는 경우 다음과 같은 지원 중단 경고가 표시됩니다.

Gradle은 이제 각 JVM 언어에 대해 별도의 출력 디렉토리를 사용하지만이 빌드는 소스 세트의 모든 클래스에 대해 단일 디렉토리를 가정합니다. 이 동작은 더 이상 사용되지 않으며 Gradle 5.0에서 제거 될 예정입니다.

이 경고를 없애려면 sourceSets.integrationTest.output.classesDirs대신로 전환하십시오 . 자세한 내용은 Gradle 4.0 출시 노트를 참조하세요 .


<hmm>으로 전환 ?? 이전과 이후는 동일합니다.
Merk

-1

저는 Gradle 6.0.1 JUnit 4.12를 사용하는 Gradle을 처음 사용합니다. 이 문제를 해결하기 위해 내가 생각 해낸 것이 있습니다.

apply plugin: 'java'
repositories { jcenter() }

dependencies {
    testImplementation 'junit:junit:4.12'
}

sourceSets {
  main {
    java {
       srcDirs = ['src']
    }
  }
  test {
    java {
      srcDirs = ['tests']
    }
  }
}

주 소스와 테스트 소스는 별도로 참조됩니다. 하나는 아래에 main있고 다른 하나는 아래에 test있습니다.

아래 testImplementation항목 dependencies은에서 소스를 컴파일하는 데만 사용됩니다 test. 주 코드에 실제로 JUnit에 대한 종속성이있는 경우 implementation아래 에도 지정 dependencies합니다.

repositories이 작업을 수행 하려면 섹션 을 지정해야했는데 이것이 최선의 / 유일한 방법이라고 생각합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.