2013-07-03 9 views
6

Dzisiaj próbowałem przełączyć projekt z testami integracyjnymi z maven na gradle. Wszystko działało dobrze, z wyjątkiem tego, że mam poważny problem z testng.Dzielenie głównej i testowanie w zaćmieniach gradle'a

Projekt wykorzystuje hibernację/JPA2 do dostępu do bazy danych i ma kilka testów zależnych od jednostki trwałości w teście/resources/META-INF/persistence.xml. Kiedy uruchamiam pakiet testowy, używając gradle, wszystko działa dobrze. Ale kiedy uruchomię xml (lub dowolną klasę testową samodzielnie) z zaćmienia, wydaje się, że próbuje użyć main/resources/META-INF/persistence.xml.

Ponieważ wykonuję większość mojej pracy przy użyciu TDD, naprawdę muszę uruchomić/debugować testy od zaćmienia. Kiedy dodaję jednostkę trwałości do pliku produkcyjnego persistence.xml, działa (pobiera nawet inne zasoby z katalogu "testowego"). Byłoby to obejściem, ale naprawdę nie podoba mi się pomysł dodania zasobów testowych do "głównego/zasobów".

Ten sam projekt działa poprawnie, gdy importuję go za pomocą starego pom.xml z 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' 
    } 
} 

Aktualizacja:

Wygenerowany plik ścieżka klasy wygląda następująco:

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

wydaje się, że wszystko łączy się w folderze bin i nie rozróżniać główne i przetestuj jak plik .classpath generowany przez maven.

+1

Brzmi jak problem z zamawianiem ścieżek klas. Czy 'main/resources' występuje przed' test/resources' w wygenerowanym pliku '.classpath'? Jeśli tak, co się stanie, jeśli zmienisz zamówienie? –

+0

Po przełączeniu głównego i testowego działa. Wydaje się, że w przeciwieństwie do maven, gradle generowane pliki ścieżek klas scalają test i główne w folderze bin. – ssindelar

+0

Dzięki Peter. Zaprowadziłeś mnie na właściwą drogę, by naprawić problem. – ssindelar

Odpowiedz

12

Problem polegał na tym, że wtyczka zaćmienia gradle domyślnie łączy test z folderem głównym. Dlatego plik persistence.xml z głównej wersji zastąpił wersję testową.

Dodanie następującego kodu rozwiąże problem, zmieniając katalogi wyjściowe wygenerowanych klas classpathentries i usuwając wpis z domyślnymi danymi wyjściowymi.

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

Aktualizacja: Odpowiednie wpisy ścieżki klas po zmianie.

<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

Nie bardzo rozumiem, jak to (niezawodnie) rozwiązuje problem. Kto upewnia się, że 'bin/test' pojawia się przed' bin/main' na ścieżce klasy testowej Eclipse? –

+0

Kod testowy i zasoby są kompilowane do innego directoy niż kod/zasoby głównego. Dlatego też nie zastępują się nawzajem. Dodałem odpowiednie odpowiedzi do klasy classpath. – ssindelar

+0

OK. Myślałem, że chcesz zastąpić główny zasób zasobem testowym. –

1

Domyślny folder wyjściowy Ustawienie do 'build' Folder wyjściowy i test 'build-test' (testowane z Gradle 2,7):

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

Powstałe wpisy pliku .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"/>