Gradle'a yeni bir kaynak kümesini nasıl eklerim?


101

Gradle yapıma (Sürüm 1.0) entegrasyon testleri eklemek istiyorum. Normal testlerimden ayrı çalışmalılar çünkü localhost'a dağıtılacak bir web uygulaması gerektiriyorlar (bu web uygulamasını test ediyorlar). Testler, ana kaynak setimde tanımlanan sınıfları kullanabilmelidir. Bunu nasıl gerçekleştiririm?

Yanıtlar:


116

Bunu anlamam biraz zaman aldı ve çevrimiçi kaynaklar harika değildi. Bu yüzden çözümümü belgelemek istedim.

Bu, ana ve test kaynak kümelerine ek olarak bir intTest kaynak kümesine sahip basit bir gradle oluşturma betiğidir:

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
Yine de bir entegrasyon testi görevi bildirmeniz ve yapılandırmanız gerekir. Dokümantasyon açısından java/withIntegrationTests, tam Gradle dağıtımında bir örnek var .
Peter Niederwieser

Teşekkürler @PeterNiederwieser Örnek derleme komut dosyamı düzelttim.
Spina

2
Ben de bunu yapmaya çalışıyordum ... çözümü gönderdiğiniz için çok teşekkür ederim :)
Igor Popov

@PeterNiederwieser Teşekkürler - lütfen bağlar mısınız? Ayrıca bu kesin durumu belgelerde ciddi şekilde eksik buluyorum: Yeni bir sourceSet tanımlamak her şey yolunda ve iyi, ancak gerçek derleme, jar, test ve whatnot hedeflerine "bunu bağlamak" hakkında hiçbir bilgi yok - bu örnekte olduğu gibi (ekleme hariç) kavanozun içine veya o sourceSet'ten yeni bir kavanoz yapma).
stolsvik

6. satırda IntelliJ kullanırken "'java' simgesi çözülemiyor" mesajı alıyorum. Neden hakkında bir fikriniz var mı?
Snekse

33

İşte bunu kullanmadan nasıl başardım 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
}

Kullanılarak test edilmiştir: Gradle 1.4 ve Gradle 1.6


2
Paylaşım için teşekkürler! Alternatif uygulamaları görmek güzel.
Spina

1
ancak java { srcDir 'src/integrationtest/java' } resources { srcDir 'src/integrationtest/resources' }şu şekilde yeniden src/<sourceSetName>/...src/integrationtest/...
beyan edildiği

Bu yaklaşıma dikkat edin. compileClasspath += sourceSets.main.runtimeClasspathiki dosya kümesini birleştiriyor. Bağımlılıklar için olağan bir çatışma çözümü yoktur. Aynı kitaplığın iki versiyonunu elde edebilirsiniz. Yapılandırmaları genişletmek buna yardımcı olacaktır.
chalimartines

22

Bu bir zamanlar 2016'da Gradle 2.x / 3.x için yazılmıştı ve çok eski !! Lütfen Gradle 4 ve sonraki sürümlerde belgelenmiş çözümlere bir göz atın


Her iki eski cevabı da özetlemek için (her iki dünyanın da en iyi ve minimum uygulanabilirliğini alın)

önce bazı sıcak sözler:

  1. önce şunu tanımlamamız gerekiyor sourceSet:

    sourceSets {
        integrationTest
    }
    
  2. genişlemeyi aşağıdaki sourceSetgelen test, kullandığımız bunun test.runtimeClasspath(tüm dependenciess içeren testve testtüretilmiş için sınıf olarak tek başına) sourceSet:

    sourceSets {
        integrationTest {
            compileClasspath += sourceSets.test.runtimeClasspath
            runtimeClasspath += sourceSets.test.runtimeClasspath // ***)
        }
    }
    
    • not ) nasılsa bu yeniden bildirilmiş / uzatmak sourceSets.integrationTest.runtimeClasspathgereklidir, ancak bu yana alakasız olmalıdır runtimeClasspathdaima genişler output + runtimeSourceSetalamadım,
  3. sadece entegrasyon testlerini çalıştırmak için özel bir görev tanımlıyoruz:

    task integrationTest(type: Test) {
    }
    
  4. Kullanılan integrationTesttest sınıflarını ve sınıf yollarını yapılandırın . javaEklentinin varsayılanları ,test sourceSet

    task integrationTest(type: Test) {
        testClassesDir = sourceSets.integrationTest.output.classesDir
        classpath = sourceSets.integrationTest.runtimeClasspath
    }
    
  5. (isteğe bağlı) testten sonra otomatik çalıştır

    integrationTest.dependsOn testi
    

  6. (isteğe bağlı) bağımlılık ekle check(böylece her zaman çalıştırıldığında buildveya çalıştırıldığında çalışır check)

    tasks.check.dependsOn(tasks.integrationTest)
    
  7. (isteğe bağlı)sourceSet otomatik algılamayı desteklemek için java, kaynakları ekleyin ve IDE'nizde bu "kısımları" oluşturun. Örneğin, IntelliJ IDEA, sourceSetmevcut değilse, her set için java dizinlerini ve kaynakları otomatik olarak oluşturacaktır :

    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)

atıfta:

Ne yazık ki, github.com/gradle/gradle/subprojects/docs/src/samples/java/customizedLayout/build.gradle veya … / gradle /… / withIntegrationTests / build.gradle üzerindeki örnek kod, bunu ele almıyor veya farklı bir / daha karmaşık / benim için daha net bir çözüm yok!


1
(!) Görünüşe göre, sourceSet geliştirmelerinin yapılandırmalar veya çıktı olmadan tek bir kullanımı, bir projeyi ilk olarak açtıktan sonra fikirde yapma hatasına neden olur. yeni "modül" (burada: integrationTest) için derleme bağımlılığı (burada: test) ilk başta kullanılamazcompileTestJava
childno͡.de

2
classesDirgeçirilmeden classesDirsgradle on 5
deFreitas

@deFreitas ipucu için teşekkürler, cevabı modası geçmiş olarak işaretledim
childno͡.de

9

Nebula-faset ortadan kaldırır Ortak metin eklentisi:

apply plugin: 'nebula.facet'
facets {
    integrationTest {
        parentSourceSet = 'test'
    }
}

Özellikle entegrasyon testleri için, bu sizin için yapılsa bile , sadece başvurun:

apply plugin: 'nebula.integtest'

Her biri için Gradle eklenti portalı bağlantıları şunlardır:

  1. nebula.facet
  2. nebula.integtest

7

Eğer kullanıyorsanız

IntelliJ'in özel kaynak kümesini test kaynakları kökü olarak tanımasını sağlamak için:

plugin {
    idea
}

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

2

İşte Gradle 4.0'dan itibaren benim için işe yarayanlar.

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
}

Sürüm 4.0'dan itibaren Gradle artık bir kaynak kümesindeki her dil için ayrı sınıf dizinleri kullanıyor. Dolayısıyla, derleme komut dosyanız kullanıyorsa sourceSets.integrationTest.output.classesDir, aşağıdaki kullanımdan kaldırma uyarısını görürsünüz.

Gradle artık her JVM dili için ayrı çıktı dizinleri kullanıyor, ancak bu yapı bir kaynak kümesindeki tüm sınıflar için tek bir dizin varsayıyor. Bu davranış kullanımdan kaldırıldı ve Gradle 5.0'da kaldırılması planlandı.

Bu uyarıdan kurtulmak için sourceSets.integrationTest.output.classesDirsbunun yerine seçeneğine geçmeniz yeterlidir. Daha fazla bilgi için Gradle 4.0 sürüm notlarına bakın .


<hmm> olarak geçilsin mi? Öncekiniz ve sonranız aynı.
Merk

-1

Gradle 6.0.1 JUnit 4.12 kullanarak Gradle'da yeniyim. İşte bu sorunu çözmek için bulduğum şey.

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

dependencies {
    testImplementation 'junit:junit:4.12'
}

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

Ana kaynak ve test kaynağı, ayrı ayrı alt alta başvuruda bulunulan Bildirimi mainaltında ve bir test.

testImplementationMadde altında dependenciessadece kaynak derleme için kullanılmaktadır test. Ana kodunuzun gerçekten JUnit'e bağımlı olması durumunda, implementationaltında da belirtmeniz gerekir dependencies.

Bunun repositoriesişe yaraması için bölümü belirtmek zorunda kaldım , bunun en iyi / tek yol olduğundan şüpheliyim.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.