Today I tried to switch an project with integration tests from maven to gradle. All worked fine except I have a serious problem with testng.
The project uses hibernate/JPA2 for database access and has a couple of tests that depend on a persistence unit in the test/resources/META-INF/persistence.xml. When I run the test suite using gradle all works fine. But when I run the xml (or any test class by itself) from eclipse it seems that it tries to use the main/resources/META-INF/persistence.xml.
Because I do most of my work using TDD, I realy need to run/debug tests from eclipse. When I add the persistence unit to the production persistence.xml it works (it even gets some other resources from the "test" dir). It would be a workaround, but I realy don't like the idea of adding test resources to "main/resources"
Same project works fine when I import it using the old pom.xml from 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'
}
}
Update:
Generated classpath file looks like this:
<?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>
It seems it merges all into the bin folder and doesn't differentiate between main and test like the .classpath file generated by maven.
To skip any task from the Gradle build, we can use the -x or –exclude-task option. In this case, we'll use “-x test” to skip tests from the build. As a result, the test sources aren't compiled, and therefore, aren't executed.
In your build. gradle, if you have minifyEnabled for debug, remove it. I had it in my project and it took ~2-3 minutes to build.
Problem was that gradle's eclipse plugin merges the test and main folder by default. Therefore the persistence.xml from main did override the test version.
Adding the following code will resolve the problem by changing the output directories of the generated classpathentries and removing the entry with the default output.
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" }
}
}
Update: Relevant classpath entries after the change.
<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"/>
Setting default output folder to 'build' and test output folder to 'build-test' (tested with Gradle 2.7):
eclipse.classpath {
defaultOutputDir = file('build')
file.withXml { n ->
n.asNode().classpathentry.findAll { [email protected]('src/test') }
.each { it.@output = 'build-test' }
}
}
Resulting .classpath file entries:
<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"/>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With