2013-07-03 8 views
6

Oggi ho provato a passare un progetto con test di integrazione da Maven a Gradle. Tutto ha funzionato bene, tranne che ho un problema serio con testng.Splitting main e test in build di eclissi di gradle

Il progetto utilizza Hibernate/JPA2 per l'accesso al database e ha un paio di test che dipendono da un'unità di persistenza nel test/risorse/META-INF/persistence.xml. Quando eseguo la suite di test utilizzando Gradle, tutto funziona correttamente. Ma quando eseguo xml (o qualsiasi classe di test da solo) da eclissi sembra che tenti di usare il main/resources/META-INF/persistence.xml.

Poiché eseguo la maggior parte del mio lavoro utilizzando TDD, ho davvero bisogno di eseguire/eseguire il debug di test da eclissi. Quando aggiungo l'unità di persistenza alla produzione persistence.xml funziona (ottiene anche altre risorse dalla directory "test"). Sarebbe una soluzione, ma non mi piace l'idea di aggiungere risorse di test a "main/resources"

Lo stesso progetto funziona bene quando lo impongo utilizzando il vecchio pom.xml di Maven.

build.gradle

apply plugin: 'java' 
apply plugin: 'eclipse' 

sourceCompatibility = 1.7 
version = '0.1' 
jar { 
    manifest { 
     attributes 'Implementation-Title': 'md', 'Implementation-Version': version 
    } 
} 

repositories { 
    mavenCentral() 
} 

dependencies { 
    compile 'org.slf4j:slf4j-api:1.7.5' 
    compile 'com.google.guava:guava:14.0.1' 
    compile 'org.hibernate:hibernate-entitymanager:4.2.2.Final' 
    compile 'org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.1.Final' 

    testCompile 'ch.qos.logback:logback-classic:1.0.13' 
    testCompile 'org.testng:testng:6.8.5' 
    testCompile 'org.dbunit:dbunit:2.4.9' 
    testCompile 'org.mockito:mockito-all:1.9.5' 
    testCompile 'org.easytesting:fest-assert-core:2.0M10' 
    testCompile 'org.hsqldb:hsqldb:2.2.9' 

} 

test { 
    useTestNG(){  
     suites 'src/test/resources/testng.xml' 
    } 
} 

Aggiornamento:

file di percorso di classe generato assomiglia a questo:

<?xml version="1.0" encoding="UTF-8"?> 
<classpath> 
    <classpathentry kind="src" path="src/main/java"/> 
    <classpathentry kind="src" path="src/main/resources"/> 
    <classpathentry kind="src" path="src/test/java"/> 
    <classpathentry kind="src" path="src/test/resources"/> 
    <classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> 
    <classpathentry exported="true" kind="con" path="org.springsource.ide.eclipse.gradle.classpathcontainer"/> 
    <classpathentry kind="output" path="bin"/> 
</classpath> 

Sembra si fonde tutto nella cartella bin e non distingue tra principale e prova come il file .classpath generato da Maven.

+1

Sembra un problema di ordinamento del percorso classe. 'Main/resources' viene prima di' test/resources' nel file '.classpath' generato? Se sì, cosa succede se cambi l'ordine? –

+0

Dopo aver commutato il main e testato funziona. Sembra che, a differenza di Maven, i file del percorso di classe generati da gradle uniscano test e main nella cartella bin. – ssindelar

+0

Grazie Peter. Mi hai portato sulla strada giusta per risolvere il problema. – ssindelar

risposta

12

Problema: il plug-in Eclipse di Gradle unisce il test e la cartella principale per impostazione predefinita. Pertanto il persistence.xml di main ha sovrascritto la versione di prova.

L'aggiunta del seguente codice risolverà il problema modificando le directory di output dei classpath generati e rimuovendo la voce con l'output predefinito.

import org.gradle.plugins.ide.eclipse.model.SourceFolder 
eclipse.classpath.file { 
    beforeMerged { classpath -> 
     classpath.entries.clear() 
    } 
    whenMerged { cp -> 
     cp.entries.findAll { it instanceof SourceFolder && it.path.startsWith("src/main/") }*.output = "bin/main" 
     cp.entries.findAll { it instanceof SourceFolder && it.path.startsWith("src/test/") }*.output = "bin/test" 
     cp.entries.removeAll { it.kind == "output" } 
    } 
} 

Aggiornamento: voci classpath rilevanti dopo il cambiamento.

<classpathentry output="bin/main" kind="src" path="src/main/java"/> 
<classpathentry output="bin/main" kind="src" path="src/main/resources"/> 
<classpathentry output="bin/test" kind="src" path="src/test/java"/> 
<classpathentry output="bin/test" kind="src" path="src/test/resources"/> 
+1

Non vedo come questo (in modo affidabile) risolva il problema. Chi si assicura che 'bin/test' venga prima di' bin/main' sul percorso della classe di test di Eclipse? –

+0

Il codice di prova e le risorse sono compilati in una directory diversa dal codice/risorse di main. Pertanto, non si cancellano più l'un l'altro. Ho aggiunto le voci del classpath pertinenti alla risposta. – ssindelar

+0

OK. Ho pensato di voler sostituire la risorsa principale con la risorsa test. –

1

cartella di destinazione predefinita Impostazione per cartella di output 'costruire' e test per 'build-test' (testato con Gradle 2.7):

eclipse.classpath { 
    defaultOutputDir = file('build') 
    file.withXml { n -> 
     n.asNode().classpathentry.findAll { [email protected]('src/test') } 
       .each { [email protected] = 'build-test' } 
    } 
} 

risultanti voci di file .classpath:

<classpathentry kind="output" path="build"/> 
<classpathentry kind="src" path="src/main/java"/> 
<classpathentry kind="src" path="src/main/resources"/> 
<classpathentry kind="src" path="src/test/java" output="build-test"/> 
<classpathentry kind="src" path="src/test/resources" output="build-test"/>