Again an abslout beginer question :-(
My gradle version is: Gradle 6.3
I initilized a small gradle project using gradle init for java and junit5
to learn junit5 and jmockit :-)
I tried to add some tutorial classes but gradle cannot resolve the hamcrest dependency :-(
// https://mvnrepository.com/artifact/org.hamcrest/hamcrest
testImplementation 'org.hamcrest:hamcrest:2.2'
as well as
// https://mvnrepository.com/artifact/org.hamcrest/hamcrest-all
testImplementation 'org.hamcrest:hamcrest-all:1.3'
on the hamcrest web site, this hint is given
http://hamcrest.org/JavaHamcrest/distributables#using-hamcrest-in-a-gradle-project
here my build.gradle file:
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java project to get you started.
* For more details take a look at the Java Quickstart chapter in the Gradle
* User Manual available at https://docs.gradle.org/6.3/userguide/tutorial_java_projects.html
*/
plugins {
// Apply the java plugin to add support for Java
id 'java'
// Apply the application plugin to add support for building a CLI application.
id 'application'
}
repositories {
// Use jcenter for resolving dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
mavenCentral()
google()
}
dependencies {
// This dependency is used by the application.
implementation 'com.google.guava:guava:28.2-jre'
testImplementation 'org.hamcrest:hamcrest:2.2'
// Use JUnit Jupiter API for testing.
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
// Use JUnit Jupiter Engine for testing.
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.0'
}
application {
// Define the main class for the application.
mainClassName = 'jmockit_examples.App'
}
test {
// Use junit platform for unit tests
useJUnitPlatform()
}
After upgrading to spock-core 2.0 , my tests are failing with below error:
org.junit.runners.model.InvalidTestClassError: Invalid test class 'com.spock.test.TestSpockSpecification':
1. No runnable methods
at org.junit.runners.ParentRunner.validate(ParentRunner.java:525)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:102)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:84)
at org.junit.runners.JUnit4.<init>(JUnit4.java:23)
at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:10)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:37)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:125)
at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:111)
I am using below configuration in my build.gradle file :
testImplementation platform("org.spockframework:spock-bom:2.0-M5-groovy-3.0") //copied from spock example
testImplementation "org.spockframework:spock-core:2.0-M5-groovy-3.0"
implementation localGroovy() //3.0.7 as I am using gradle 7
I am running these test with junit 4 ,Can someone please help
Spock 2.0 builds on top of JUnit 5 and does not work with legacy JUnit 4. Also, it has been out for some time now, and there are no reasons to use milestones.
See this for a full example. Pay attention to the useJUnitPlatform part. E.g.:
dependencies {
testImplementation platform("org.codehaus.groovy:groovy-all:3.0.9")
testImplementation platform("org.spockframework:spock-bom:2.0-groovy-3.0")
testImplementation "org.spockframework:spock-core"
testRuntimeOnly "net.bytebuddy:byte-buddy:1.11.18" // allows mocking of classes (in addition to interfaces)
testRuntimeOnly "org.objenesis:objenesis:3.2" // allows mocking of classes without default constructor (together with ByteBuddy or CGLIB)
}
test {
useJUnitPlatform()
}
We've use mapstruct 1.20.final for approx 1.5 years with various Gradle versions - latest gradle 4.10.2. We want to switch to Gradle 5.4.1, which works with everything except mapstruct. Our working setup was not clean. Hence decided to start over. Old working setup was a hybrid form of the example on Github and the now obsolete setup.
Started again with http://mapstruct.org/news/2013-07-08-using-mapstruct-with-gradle as a base. Have this strong feeling this is NOT compatible with Gradle 5. Release notes Gradle 5 states: Gradle will no longer automatically apply annotation processors that are on the compile classpath — use CompileOptions.annotationProcessorPath instead. Tried to do it as described in https://blog.gradle.org/incremental-compiler-avoidance#about-annotation-processors. This works for 4.10.2. With Gradle 5 this results in the following error:
Execution failed for task ':eu.educator.rest:compileJava'.
Cannot specify -processorpath or --processor-path via CompileOptions.compilerArgs. Use the CompileOptions.annotationProcessorPath property instead.
We have a multi-project setup. In the project 'rest' the sanitized build.gradle looks like this:
plugins {
id 'net.ltgt.apt' version '0.21'
}
configurations {
apt
}
dependencies {
apt libraries.mapstruct_processor
compileOnly libraries.mapstruct_processor
}
compileJava {
options.annotationProcessorPath = configurations.apt
}
Have tried multiple setups in the last 1.5 days. Can NOT get it to work. So if anyone has mapstruct working with Gradle 5 I really would appreciate a working build.gradle, hints, pointers.
PS. How can I replace the following with a Gradle 5 compliant version.
tasks.withType(JavaCompile) {
options.compilerArgs = [
'-Amapstruct.suppressGeneratorTimestamp=true'
]
}
Since latest Gradle version ( >= 4.8 I would say) you can simplify your build script as follows ; you don't need apt plugin anymore, just use annotationProcessor Gradle configuration :
ext{
mapstructVersion = "1.2.0.Final"
}
dependencies{
// ...
// --- Mapstruct ---------------------------------
compileOnly("org.mapstruct:mapstruct-jdk8:${mapstructVersion}")
annotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}"
}
compileJava {
options.annotationProcessorPath = configurations.annotationProcessor
// if you need to configure mapstruct component model
options.compilerArgs << "-Amapstruct.defaultComponentModel=spring"
}
Note: by default, Gradle will generate sources into directory :build/generated/sources/annotationProcessor/java/main
But this is configurable, for example:
compileJava {
// ...
options.setAnnotationProcessorGeneratedSourcesDirectory( file("$projectDir/src/generated/java"))
I am trying to use JUnit 5 with Gradle after I succeeded in running a JUnit 4 test.
Expected result: Tthe JUnit 4 test gave a nice 'passed' in the output and an html report in build/reports/tests.
Actual result: The JUnit 5 test as below does not output anything besides (...) build succesful, while I know the test is not actually run since there is no test log output passed/skipped/failed, and putting a fail in the test keeps the build successful.
Running gradle test --info yields Skipping task ':testClasses' as it has no actions. among a lot of I think mostly unrelevant output.
Surprisingly, it also says Executing task ':test' and Generating HTML test report... Finished generating test html results and similar for the xml in build/test-results/test, while the xml is not generated, the html shows no tests run and no errors, and the test is indeed not run.
What I also think very interesting, is that gradle test --debug yields
[TestEventLogger] Gradle Test Run :test STARTED
[org.gradle.api.internal.tasks.testing.junit.JUnitDetector] test-class-
scan : failed to scan parent class java/lang/Object, could not find the class file
[TestEventLogger]
[TestEventLogger] Gradle Test Run :test PASSED
while my only test contains
fail("test fails");
which I think is very strange!
My build file is
apply plugin: 'java'
test {
dependsOn 'cleanTest' // run tests every time
}
sourceSets {
main {
java {
srcDirs 'src'
}
}
test {
java {
srcDirs 'test'
}
}
}
repositories {
mavenCentral()
}
dependencies {
// when using this, it worked with a junit 4 test
// testCompile 'junit:junit:4.10'
// this should be needed for junit 5 (using M4 is required since IJ 2017.1.2
testCompile("org.junit.jupiter:junit-jupiter-api:5.0.0-M4")
}
test {
testLogging {
events "passed", "skipped", "failed"
}
}
My test is
package mypackage;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class HelloWorldTest {
#Test
public void testHelloWorld(){
assertEquals(2, 1+1, "message");
}
}
My folder structure is, using package mypackage,
java-template-project
--- src
--- mypackage
--- HelloWorld.java
--- test
--- mypackage
--- HelloWorldTest.java
and in IntelliJ 2017.1.3, which I am using, the module structure looks like this
java-template-project
--- java-template-project_main
--- src/mypackage
--- HelloWorld(.java)
--- java-template-project_test
--- test/mypackage
--- HelloWorldTest(.java)
because Gradle nowadays wants the source and tests in their own package.
What I tried
Obviously this is not the first question about this topic, all the relevant questions I found are
Gradle project running jUnit 5 tests in IntelliJ
But as you can see this is for older versions of IntelliJ, and I am already using the syntax for IJ 2016.3.3 and higher according to one of the answers, in in the one JUnit dependency line, so that should be okay.
Upgrade from JUnit 4 to JUnit 5 in intellij with gradle
Links back to above question, and links to this Jetbrains blog which uses the same line as above question. Also links to:
Integrate JUnit 5 tests results with Intellij test report
This one shows, in the question, as dependency also
testRuntime("org.junit.vintage:junit-vintage-engine:5.0.0-M1")
which is explained in Why were JUnit Jupiter and JUnit Vintage separated When I Running TestCase in IntelliJ?
Well, when I ran it, the output showed it couldn't find this version but according to the Maven Repository this one is for JUnit 5:
testRuntime("org.junit.vintage:junit-vintage-engine:4.12.0-M4")
The answers there note that you can just run the tests within IntelliJ since the later versions have JUnit 5 support. I know, and the test runs fine when I run from within IntelliJ. But I want to use Gradle (and Travis, which needs dependency management).
How to capture stdout/stderr in junit 5 gradle test report?
I tried using
testCompile("org.junit.platform:junit-platform-gradle-plugin:1.0.0-M3")
testCompile("org.junit.jupiter:junit-jupiter-engine:5.0.0-M3")
but results didn't change.
My template project is located on https://github.com/PHPirates/java-template-project but this question should contain all information necessary.
New: JUnit 5 support in Gradle 4.6
As pointed out in this GitHub issue from Gradle 4.6 onwards JUnit 5 is supported!
Official release notes of 4.6 (at the moment of editing the latest, but check the GitHub releases page to make sure you use the latest version) at docs.gradle.org. The old setup will still work, but using this makes the build file a lot cleaner.
[Edit May 2019] As #deFreitas pointed out in his answer, the JUnit documentation has improved and now they provide a complete example at https://github.com/junit-team/junit5-samples/tree/r5.4.0/junit5-jupiter-starter-gradle, see especially the build.gradle there. Fortunately it turns out to be effectively the same as the one from this answer.
Update Gradle
First, make sure you are using the latest Gradle version, check latest releases at their GitHub releases. If that is for example 4.6, run in a terminal in your project location gradlew wrapper --gradle-version=4.6 or make sure to update this line in your gradle/wrapper/gradle-wrapper.properties file: distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip.
How to use the built-in JUnit 5
Then with the java files, directory structure etc. from the question the build.gradle file will be (using the new plugins block)
plugins {
id 'java'
}
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.0.3'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.0.3'
}
// These lines can be removed when you use the default directories src/main/kotlin and src/test/kotlin
sourceSets {
main.java.srcDirs += 'src'
main.resources.srcDirs += 'src'
test.java.srcDirs += 'test'
test.resources.srcDirs += 'test'
}
// Java target version
sourceCompatibility = 1.8
test {
// Enable JUnit 5 (Gradle 4.6+).
useJUnitPlatform()
// Always run tests, even when nothing changed.
dependsOn 'cleanTest'
// Show test results.
testLogging {
events "passed", "skipped", "failed"
}
}
PS For the absolute minimal version, see Ray's answer.
Android (See this post: JUnit 5 for Android testing)
On Android I managed to run the JUnit 5 test from the question by adding the following to my app module build file. As you can see the dependencies are the same, but I didn't need useJUnitPlatform() and the test configuration block is slightly different.
apply plugin: 'com.android.application'
// In fact I am not sure you need this, but I had it included to run Spek tests anyway
apply plugin: 'de.mannodermaus.android-junit5'
repositories {
mavenCentral()
jcenter()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1'
}
android {
// I'm omitting your other configurations like compileSdkVersion, buildTypes etc.
testOptions {
unitTests.all {
// Always run tests, even when nothing changed.
dependsOn 'clean'
// Show test results.
testLogging {
events "passed", "skipped", "failed"
}
}
}
}
however, it only works for me when I execute the Gradle test task, not when I run the check task. As usual, I test this by creating a failing test and then I try if the Gradle task passes or fails.
You need the engines for both JUnit versions, and you need to apply the JUnit platform gradle plugin. I do not see that in your gradle file. Here is a working gradle build executing both JUnit 4 and 5:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath ("org.junit.platform:junit-platform-gradle-plugin:1.0.0-M4")
}
}
apply plugin: 'org.junit.platform.gradle.plugin'
...
dependencies {
...
testCompile("junit:junit:4.12")
testRuntime("org.junit.vintage:junit-vintage-engine:4.12.0-M4")
testCompile("org.junit.jupiter:junit-jupiter-api:5.0.0-M4")
testRuntime("org.junit.jupiter:junit-jupiter-engine:5.0.0-M4")
// Enable use of the JUnitPlatform Runner within the IDE
testCompile("org.junit.platform:junit-platform-runner:1.0.0-M4")
}
junitPlatform {
details 'tree'
}
See the JUnit doc form more information on that.
just adding to the knowledge base, i just got the following to work with gradle 4.7:
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.1.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.1.1'
}
test {
useJUnitPlatform()
}
Due to github issue built-in support for JUnit 5, scheduled for Gradle 4.6
Thus since gradle 4.6 your expected result have to be the same as actual result.
Expected result: Tthe JUnit 4 test gave a nice 'passed' in the output
and an html report in build/reports/tests.
UPD:
gradle 4.6-rc-1 was released on 16th of February 2018 and this version provides the built-in support for junit 5.
To enable junit 5 support you need to update gradle wrapper:
gradle wrapper --gradle-version=4.6-rc-1
and add just one line to build.gradle:
test {
useJUnitPlatform()
}
Checkout junit official documentation of how to use junit 5 with gradle.
build.gradle
plugins {
id 'java'
}
repositories {
mavenCentral()
}
dependencies {
testImplementation('org.junit.jupiter:junit-jupiter:5.4.0')
}
test {
useJUnitPlatform()
testLogging {
events "passed", "skipped", "failed"
}
}
Maybe something helpful for those who were struck with this problem when trying to integrate JUnit5 with gradle version 4.10.
Could not find method test() for arguments [build_dzas89s5z18l3bfyn6b3q0dxv$_run_closure2$_closure9#8e60c6] on project ':app' of type org.gradle.api.Project.
Actually, with 4.10 you don't need to add this test configuration block in build.gradle to enable JUnit5.
test {
useJUnitPlatform()
}
It should work fine just by adding the necessary dependencies of jupitor-api and jupitor-engine.
I tried to explore release notes of 4.10 but couldn't find anything about this change. If someone knows more about the "Why" behind it then please englighten me as well.
Using the latest version of gradle (2.10) with the Scala Plugin enabled, I'm trying to execute the tests located at src/test/scala.
But there seems to be no tasks to run these:
$ ./gradlew tasks
....
Verification tasks
------------------
check - Runs all checks.
test - Runs the unit tests.
None of these 2 tasks will execute my Scala tests. The only tests that get executed are those in src/test/java. My Scala tests tests are using Specs2 using the following dependencies for test (build.gradle):
apply plugin: 'scala'
dependencies {
testCompile(
'org.specs2:specs2-core_2.12.0-M3:3.6.6-scalaz-7.2.0'
)
}
I checked: the tests are getting compiled when using ./gradlew compileTestScala.
What needs to be done to execute these tests?
Ok, it was easy:
import org.specs2.runner.JUnitRunner
#RunWith(classOf[JUnitRunner])
class FooSpec extends Specification {
// test code
...
}
Another solution: using gradle plugin com.github.maiflai.scalatest
For such solution, Scala tests will be ran using org.scalatest.tools.Runner.
dependencies {
implementation 'org.scala-lang:scala-library:2.13.3'
testImplementation 'org.scalatest:scalatest_2.13:3.2.0'
testImplementation 'junit:junit:4.13'
testImplementation 'com.vladsch.flexmark:flexmark-all:0.35.10'
}
version of flexmark is important because of scalatest framework hard coded such version in their code