I'm creating another source set for integration testing, but every time my gradle rebuilds it turns my main test root folder back to source root folder (blue), when I want it to be test root folder (green). What do I need to configure in my build.gradle so that this is fixed?
sourceSets {
integration {
compileClasspath += sourceSets.main.output
runtimeClasspath += sourceSets.main.output
}
}
configurations {
intTestRuntimeOnly.extendsFrom runtimeOnly
intTestImplementation.extendsFrom testImplementation
}
dependencies {
intTestImplementation 'junit:junit:4.12'
}
task integrationTest(type: Test) {
description = 'Runs integration tests.'
group = 'verification'
testClassesDirs = sourceSets.integration.output.classesDirs
classpath = sourceSets.integration.runtimeClasspath
shouldRunAfter test
}
check.dependsOn integrationTest
Everytime I manually change it to testsources root and rebuild it just turns back to blue.
I followed this documentation https://docs.gradle.org/current/userguide/java_testing.html#sec:configuring_java_integration_tests
Thanks
Related
Let's assume a java project with a project structure like so:
src
itest
java
SourcesTestsItest.java
main
java
gradle_pr
pojo.java
test
java
gradle_pr
SourceSetsTest.java
build.gradle
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java Library project to get you started.
* For more details take a look at the Java Libraries chapter in the Gradle
* User Manual available at https://docs.gradle.org/6.3/userguide/java_library_plugin.html
*/
plugins {
// Apply the java-library plugin to add support for Java Library
id 'java-library'
}
repositories {
// Use jcenter for resolving dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
}
sourceSets{
itest{
compileClasspath += sourceSets.main.output
runtimeClasspath += sourceSets.main.output
java{
srcDirs("src/itest")
}
}
}
configurations{
itestImplementation.extendsFrom(testImplementation)
itestRuntimeOnly.extendsFrom(testRruntimeOnly)
}
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:28.2-jre'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
implementation('org.apache.httpcomponents:httpclient:4.5.12')
itestImplementation('com.google.guava:guava:29.0-jre')
}
task printSourceSetInformation(){
doLast{
sourceSets.each { srcSet ->
println "["+srcSet.name+"]"
print "-->Source directories: "+srcSet.allJava.srcDirs+"\n"
print "-->Output directories: "+srcSet.output.classesDirs.files+"\n"
print "-->Compile classpath:\n"
srcSet.compileClasspath.files.each {
print " "+it.path+"\n"
}
println ""
}
}
}
task itest(type: Test) {
description = "Run integration tests"
group = "verification"
testClassesDirs = sourceSets.itest.output.classesDirs
classpath = sourceSets.itest.runtimeClasspath
}
Why do I have use the following lines
compileClasspath += sourceSets.main.output
runtimeClasspath += sourceSets.main.output
if the pojo class should be visible in test class under itest as they are in the same package?. How does the default configuration work so test cases can see the generated compiled code of main?
Gradle doesn't know per se how your configurations depend on each other (i.e. it could be that the main configuration depends on itest or the other way around).
For the main and test configurations this dependency is established for you when you apply the java-library plugin.
I have a Gradle-based project in Eclipse which I want to test using JUnit 5. It does not have any tests right now, so I wanted to add a dummy one (e.g., assertEquals(true, true)) to make sure that Gradle can run the test.
However, I experience two problems:
1) When I want to create JUnit test case as "Project Right Click --> New --> JUnit Test Case", it creates a test case inside /src directory. See the image below:
2) When I try to build my Gradle configuration, I get the following output:
> Task :compileJava FAILED
/home/.../src/main/java/TestFoo.java:1: error: package org.junit does not exist
import static org.junit.Assert.*;
^
As far as I understand, the test case cannot resolve the package org.junit. At the same time, Eclipse does not let me create a proper JUnit test case in the proper /test directory.
What do you think could be a possible solution here? I tried finding a way to override default test directory, but could not find any way to do that.
P.S. This is not duplicate as I tried this and I have all dependencies declared. The following snippet is the build.gradle contents (I apologize, but I cannot display all of its contents due to confidentiality reasons):
...
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
...
testCompile group: 'junit', name: 'junit', version: '4.12'
// Reference: https://www.baeldung.com/junit-5-gradle
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1'
}
run {
...
}
test {
useJUnitPlatform {
includeTags 'fast'
excludeTags 'slow'
}
}
shadowJar {
mergeServiceFiles()
manifest {
attributes 'Implementation-Title': rootProject.name
attributes 'Implementation-Version': rootProject.version
attributes 'Implementation-Vendor-Id': rootProject.group
attributes 'Created-By': 'Gradle ' + gradle.gradleVersion
attributes 'Main-Class': mainClassName
}
archiveName rootProject.name + '-' + rootProject.version + '.jar'
}
You can either use this: How to create unit tests easily in eclipse (answer with most upvotes)
Or install this plugin: https://moreunit.github.io/MoreUnit-Eclipse/ (and create test using Ctrl + J)
I'm fairly new to Gradle and am using version 5.0. I'm reasonably proficient in Cucumber.
I've got a simple project that builds a jar file and runs JUnit tests on them. It all works well.
Now I want to add Cucumber to the project but I want my .feature files and the related stepdefs in an alternative source-tree (sourceSet in Gradle terminology).
The sources can be found on Github, which holds a sample project.
My source tree should look like this:
src/
cucumberTest/
java/
/...
resources/
/...
main/
java/
/...
resources/
/...
test/
/java
/...
resources/
/...
When I put the .feature files in cucumberTest/resources and the stepdef java files in test/java my Cucumber tests run fine. But when the stepdefs are in cucumberTest/java Cucumber can't find the files and I get the error that they are not defined.
Undefined scenarios:
src/cucumberTest/resources/is_it_saturday_yet.feature:4 # Sunday isn't Saturday
2 Scenarios (1 undefined, 1 passed)
6 Steps (1 skipped, 2 undefined, 3 passed)
0m0.134s
My build.gradle file is this:
plugins {
id 'java-library'
id 'java'
id 'idea'
}
repositories {
jcenter()
mavenCentral()
}
archivesBaseName = "helloworld"
version = '1.0'
dependencies {
api 'org.apache.commons:commons-math3:3.6.1'
implementation 'com.google.guava:guava:26.0-jre'
testImplementation 'junit:junit:4.12'
testCompile("junit:junit:4.12")
testCompile('org.junit.jupiter:junit-jupiter-api:5.3.2')
testCompile('org.junit.jupiter:junit-jupiter-params:5.3.2')
testRuntime('org.junit.jupiter:junit-jupiter-engine:5.3.2')
testRuntime("org.junit.vintage:junit-vintage-engine:5.3.2")
testCompile 'io.cucumber:cucumber-java:4.2.0'
testCompile 'io.cucumber:cucumber-junit:4.2.0'
}
configurations {
cucumberRuntime {
extendsFrom testRuntime
}
}
test {
useJUnitPlatform ()
testLogging {
events "passed", "skipped", "failed"
}
}
// Cucumber stuff:
sourceSets {
cucumberTest {
compileClasspath += sourceSets.main.output
runtimeClasspath += sourceSets.main.output
}
}
configurations {
cucumberTestImplementation.extendsFrom implementation
cucumberTestRuntimeOnly.extendsFrom runtimeOnly
}
dependencies {
testCompile 'io.cucumber:cucumber-java:4.2.0'
testCompile 'io.cucumber:cucumber-junit:4.2.0'
}
task cucumberTest() {
dependsOn assemble, compileTestJava
doLast {
javaexec {
main = "cucumber.api.cli.Main"
classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output + sourceSets.cucumberTest.output
args = ['--plugin', 'pretty', '--glue', 'stepdefs.hellocucumber', 'src/cucumberTest/resources']
}
}
}
wrapper {
gradleVersion = '5.0'
}
I've looked all over the web, but I feel like I'm the only one who wants to use cucumber-jvm with Gradle 5 and have the BDD tests (cucumber) separated from the TDD tests (JUnit).
I can take the easy route and just mix them both, but apart from being a little puritan and have BDD and TDD separated, I also want to understand what's going on and why it's not working.
Help is appreciated. Thanks.
Iwan
With the help of Bart Kors, a good friend of mine, I was able to get it to work as intended. I updated the Github repository to include the working code. Do a clone of TrheeAxis/hellocucumber to get the working code.
I would like to add an additional "source set" to a Kotlin project that will contain integration tests. I have seen a few posts that talk about doing it for either a vanilla Java project or for Kotlin but using Groovy rather than the Kotlin Gradle DSL.
In summary, using the Kotlin Gradle DSL:
how to add an additional "source set" that can contain Kotlin code, Java code & resources for the purpose of separating integration tests from regular unit tests?
how to add an additional task and configuration to run the integration tests separately from unit tests?
I would expect the directory structure to look something like:
src
main
java
kotlin
resources
test
java
kotlin
resources
integration
java
kotlin
resources
Related:
https://ryanharrison.co.uk/2018/07/25/kotlin-add-integration-test-module.html
https://www.petrikainulainen.net/programming/gradle/getting-started-with-gradle-integration-testing/
How do I add a new sourceset to Gradle?
Thanks
First, create source set and configuration:
sourceSets {
create("intTest") {
compileClasspath += sourceSets.main.get().output
runtimeClasspath += sourceSets.main.get().output
}
}
val intTestImplementation: Configuration by configurations.getting {
extendsFrom(configurations.implementation.get())
}
val intTestRuntimeOnly: Configuration by configurations.getting {
extendsFrom(configurations.runtimeOnly.get())
}
And then, create the task to run them:
val integrationTest = task<Test>("integrationTest") {
description = "Runs integration tests"
group = "verification"
testClassesDirs = sourceSets["intTest"].output.classesDirs
classpath = sourceSets["intTest"].runtimeClasspath
shouldRunAfter("test")
}
Also, you can add dependencies to be used by the new source set. For instance:
intTestImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion")
intTestRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junitVersion")
You must add following configuration to your build.gradle file
configurations {
integrationTestImplementation.extendsFrom implementation
integrationTestRuntimeOnly.extendsFrom runtimeOnly
}
dependencies {
intTestImplementation 'junit:junit:4.12'
...
}
sourceSets {
integrationTest {
kotlin {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
srcDir file('src/integrationTest/kotlin')
}
}
}
task integrationTest(type: Test, dependsOn: []) {
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
useJUnitPlatform()
}
source:
https://docs.gradle.org/current/userguide/java_testing.html#sec:configuring_java_integration_tests
I'm trying to migrate java project from maven to gradle. The problem is very tricky classpath dependency configuration for tests now.
Our maven-surefire-plugin configuration:
<includes>
<include>**/SomeTest1.java</include>
</includes>
<classpathDependencyExcludes>
<classpathDependencyExclude>com.sun.jersey:jersey-core</classpathDependencyExclude>
</classpathDependencyExcludes>
There are different classpathes for different test-classes. How can I implement it with Gradle?
First of all you need to differ your tests sources into separate sourceSets. Say, we need to run tests from package org.foo.test.rest with a little different runtime classpath, than other tests. Thus, its execution will go to otherTest, where remain tests are in test:
sourceSets {
otherTest {
java {
srcDir 'src/test/java'
include 'org/foo/test/rest/**'
}
resources {
srcDir 'src/test/java'
}
}
test {
java {
srcDir 'src/test/java'
exclude 'org/foo/rest/test/**'
}
resources {
srcDir 'src/test/java'
}
}
}
After that, you should make sure that otherTest has all required compile and runtime classpaths set correctly:
otherTestCompile sourceSets.main.output
otherTestCompile configurations.testCompile
otherTestCompile sourceSets.test.output
otherTestRuntime configurations.testRuntime + configurations.testCompile
The last thing is to exclude (or include) unneeded runtime bundles from test:
configurations {
testRuntime {
exclude group: 'org.conflicting.library'
}
}
And to create Test Gradle task for otherTest:
task otherTest(type: Test) {
testClassesDir = sourceSets.otherTest.output.classesDir
classpath += sourceSets.otherTest.runtimeClasspath
}
check.dependsOn otherTest
Use next workaround:
Create source set for needed tests
Add configurations for created sourceSet
Add task for run test with custom configuration
Configure test task dependOn customized test task
Configure Report plugin for generate beautiful html report :)
Like this getting started