2013-07-03 5 views
6

Heute habe ich versucht, ein Projekt mit Integrationstests von Maven zu Gradle zu wechseln. Alles hat gut funktioniert, außer ich habe ein ernsthaftes Problem mit dem Testen.Splitting Main und Test in Gradle's Eclipse baut

Das Projekt verwendet Hibernate/JPA2 für den Datenbankzugriff und verfügt über einige Tests, die von einer Persistenzeinheit in der Datei test/resources/META-INF/persistence.xml abhängen. Wenn ich die Testsuite benutze, funktioniert alles gut. Aber wenn ich die XML-Datei (oder eine andere Testklasse) von Eclipse aus starte, scheint es, dass sie versucht, die Datei main/resources/META-INF/persistence.xml zu verwenden.

Da ich die meiste Arbeit mit TDD mache, muss ich wirklich Tests von Eclipse ausführen/debuggen. Wenn ich die persistence-Unit zur production persistence.xml hinzufüge, funktioniert es (es erhält sogar einige andere Ressourcen aus dem "test" -Dir). Es wäre ein Workaround, aber ich mag wirklich nicht die Idee, Testressourcen zu "Main/Ressourcen" hinzufügen

Das gleiche Projekt funktioniert gut, wenn ich es mit der alten pom.xml von Maven importieren.

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' 
    } 
} 

Update:

generiert Classpath-Datei sieht wie folgt aus:

<?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> 

Es scheint, es ist alles in den Ordner bin übergeht und unterscheidet nicht zwischen Haupt und testen Sie wie die von Maven generierte .classpath-Datei.

+1

Klingt wie ein Klassenpfad-Bestellproblem. Steht "main/resources" in der generierten '.classpath' Datei vor' test/resources'? Wenn ja, was passiert, wenn Sie die Bestellung ändern? –

+0

Nach dem Umschalten von Haupt und Test funktioniert es. Es scheint, dass im Gegensatz zu maven, gradle generierte Klassenpfad-Dateien test und main in den bin-Ordner zusammenführen. – ssindelar

+0

Danke Peter. Sie haben mich auf den richtigen Weg gebracht, um das Problem zu beheben. – ssindelar

Antwort

12

Problem war, dass Gradle Eclipse-Plugin standardmäßig den Test-und Hauptordner zusammenführt. Daher hat die Datei persistence.xml von main die Testversion überschrieben.

Durch Hinzufügen des folgenden Codes wird das Problem behoben, indem die Ausgabeverzeichnisse der generierten claspathentries geändert und der Eintrag mit der Standardausgabe entfernt wird.

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" } 
    } 
} 

Aktualisierung: Relevante Klassenpfadeinträge nach der Änderung.

<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

Ich sehe nicht ganz, wie dies (zuverlässig) das Problem löst. Wer stellt sicher, dass "bin/test" auf dem Eclipse-Testklassenpfad vor "bin/main" steht? –

+0

Der Testcode und die Ressourcen werden in einem anderen Verzeichnis kompiliert als der Code/die Ressourcen von main. Daher überschreiben sie sich nicht mehr gegenseitig. Ich fügte der Antwort die relevanten Classpath-Einträge hinzu. – ssindelar

+0

OK. Ich dachte, Sie möchten die Hauptressource durch die Testressource ersetzen. –

1

Einstellung Standardausgabeordner 'build' und Testausgabeordner 'build-test' (getestet mit Gradle 2.7):

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

Resultierende .classpath Dateieinträge:

<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"/> 
Verwandte Themen