Enable junit extensions autodetection with gradle - gradle

I would like to enable by default junit extension autoDetection on my project
if i understantd I should use -Djunit.jupiter.extensions.autodetection.enabled=true when i launch my build.
But i want to enable by default without extra parameters in the command line and in all my subModule.
I thing something like that should be good :
allprojects {
test {
//put an option here
useJUnitPlatform()
}
}
But i've no clue of which option to put in my build.gradle.

In Gradle you can use the system properties extension:
test {
// ...
systemProperty("junit.jupiter.extensions.autodetection.enabled", true)
}
See JUnit 5 User Guide for further details.

Related

Why isn't #DisplayName working for me in JUnit 5?

For some reason, I'm really having a hard time getting display names to actually be respected in JUnit 5 with Kotlin.
Here's a test file I created for the purpose of example:
import org.assertj.core.api.Assertions
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
#DisplayName("Example Test")
class ExampleTest {
#Test
#DisplayName("test name")
fun myTest() {
Assertions.assertThat(false).isTrue()
}
}
But instead of these names being used, it's showing the actual class/method name as if they weren't annotated with #DisplayName at all. Here's the output from ./gradlew test:
project.path.ExampleTest > myTest() FAILED
org.opentest4j.AssertionFailedError at ExampleTest.kt:12
25 tests completed, 1 failed
> Task :test FAILED
I keep thinking there must be something wrong with my Gradle configuration, but the setup is pretty simple so I don't know what I could be doing wrong.
Here's my build.gradle.kts:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.3.60"
id("org.jmailen.kotlinter") version "2.1.2"
id("org.jetbrains.kotlin.plugin.serialization") version "1.3.60"
}
version = "0.1"
repositories {
mavenCentral()
jcenter()
}
dependencies {
implementation(kotlin("stdlib-jdk8"))
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.14.0")
testImplementation("org.junit.jupiter:junit-jupiter:5.5.2")
testImplementation("org.assertj:assertj-core:3.14.0")
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
tasks.test {
useJUnitPlatform()
}
Really scratching my head at this point, so any ideas would be appreciated. It's not using the names I give to my dynamic tests either (in conjunction with #TestFactory), which is particularly annoying.
Finally figured this out. It was an IntelliJ configuration issue. (The display names are never displayed in the command line anyway apparently.)
Turns out I had it configured to use the Gradle test runner instead of the IntelliJ one, which doesn't show custom display names. The solution was to go into IntelliJ settings -> Build, Execution, Deployment -> Gradle and under "Run tests using" select "IntelliJ IDEA"
Thanks go to JBNizet for pointing out that display names are supposed to show up in the HTML test report that Gradle generates but not in the command line, which helped me determine that this was an IntelliJ-specific issue.
It's because IntelliJ uses gradle test runner by default and it does not allow custom display name.
The solution is really simple you just need to change the default test runner from "Gradle" to "IntelliJ Idea".
Preferences
Build, Execution, Deployment
Build Tools
Gradle
Run tests using = IntelliJ Idea
How to change default test runner in IntelliJ Idea
Truth is, for me, after I undid the changes suggested on this post and selected the check icon to the right of the green play button, the description of the tests started to show.
I managed to get it working in surefirereports by using the configuration
in
https://maven.apache.org/surefire/maven-surefire-plugin/examples/junit-platform.html#Surefire_Extensions_and_Reports_Configuration_for_.40DisplayName
it displays output like this
"name" is from #DisplayName

Gradle global plugin repository with Kotlin DSL

I am new to Gradle, but need to build an opensource project that uses it, from my machine on the corporate network. The project has recently moved to Kotlin DSL, so some plugins are required.
I need to use our corporate Nexus server to fetch the plugin dependencies, and I would like to set this globally, because I don't want to have to modify the settings.gradle.kts in all the projects (I've tried this and it works)
If I want to do this globally, I understand from https://docs.gradle.org/current/userguide/plugins.html#sec:plugin_management that I need to have an init.gradle.kts file in my USER_HOME/.gradle directory. That's what I did, here's the content of the file :
settingsEvaluated { settings ->
settings.pluginManagement {
repositories {
mavenLocal()
maven("https://my_corporate_nexus/")
}
}
}
But when I then trigger my build, here's what I get :
* What went wrong:
Script compilation errors:
Line 1: settingsEvaluated { settings ->
^ None of the following functions can be called with the arguments supplied:
public open fun settingsEvaluated(p0: Closure<(raw) Any!>): Unit defined in Init_gradle
public open fun settingsEvaluated(p0: Action<in Settings!>): Unit defined in Init_gradle
public final fun settingsEvaluated(p0: Settings!.() -> Unit): Unit defined in Init_gradle
Below are my version details, as provided by gradle -v :
Gradle 4.9
Kotlin DSL: 0.18.4
Kotlin: 1.2.41
Groovy: 2.4.12
So it looks likes there's something obvious I am missing.
Any idea what it could be ?
it seems to work with :
settingsEvaluated {
settings.pluginManagement {
repositories {
mavenLocal()
maven("https://my_corporate_nexus/")
}
}
}
no settings -> .
I am not sure whether documentation is wrong or if my setup is specific though...

Changing configuration with the gretty plugin?

I haven't done anything with Gradle for a while, so it appears I've forgotten how configuration resolution works.
I'm trying to use the gretty plugin (instead of core, deprecated jetty), but I cannot seem to create a custom configuration.
I've boiled it down to a very short, simple script (using Gradle 3.4):
buildscript {
repositories {
maven {
url 'https://plugins.gradle.org/m2/'
}
}
dependencies {
classpath 'org.akhikhl.gretty:gretty:1.4.0'
}
}
plugins {
id 'org.akhikhl.gretty' version '1.4.0'
}
configurations {
fooTest
}
configurations.fooTest.each {
println it.toString()
}
It seems to not like me iterating over the fooTest configuration.
Assuming I need to know the dependencies for that configuration (I stripped that part from the code above)
What am I doing wrong here?
The script above gives me this:
org.gradle.api.InvalidUserDataException: Cannot change strategy of configuration ':fooTest' after it has been resolved.
The key point here was that I needed an unresolved configuration to loop over. Admittedly this information was neglected in the initial description as I didn't know it was critical information. We needed to loop over the files in the dependency and copy/unzip them into certain locations.
However, we cannot do that with a resolved configuration. That said, we can copy the configuration into a unresolved one, and loop over that instead:
configurations.fooTest.copy().each {
println it.toString()
}
This will successfully print out the files involved in the dependency (or unzip them, as my case needs).

Gradle exclude a specific subproject from full build

In our Gradle project, we want to add a new module for functional-tests that needs to be able to access dependencies from other subprojects but still not be run as part of the full project build. If I try this, it still gets built:
def javaProjects() {
return subprojects.findAll { it.name != 'functional-tests' }
}
configure(javaProjects()) {
...
}
project(':functional-tests') {
....
}
The result is the same even if I move the functional-tests build to a separate build.gradle file of its own. Can someone point out how to achieve this?
I found a better solution to be to exclude the functional tests from running on the command line or via the build file.
For example, to run all tests except the functional tests, run:
$ gradle check -x :functional-tests:check
Then when building the project, you can let the subproject build but exclude their tests from running.
$ gradle clean assemble -x :functional-tests:check
A better option is do disable the functional tests in your build file unless a property is set. For example, in your build.gradle you'd add:
project('functional-tests') {
test {
onlyIf {
project.hasProperty("functionalTests")
}
}
}
This way, functional tests are always skipped unless you specify a specific build property:
$ gradle check
$ gradle -PfunctionalTests check
Hope that helps!
I do it like this:
//for all sub projects
subprojects {
if (it.name != 'project name') {
//do something
}
}
by this way, I can exclude some special project in subprojects.
you can also use it in allprojects or project.
As far as I know it's not possible to deactivate or exclude project after it as been included in settings.gradle. Therefore it maybe done in the following way in settings.gradle:
include 'p1', 'p2', 'p3'
if (any_condition_here) {
include 'functional-tests'
}
It will require additional checking in build.gradle - to configure the project if it's included.
What also comes to my head is -a command line switch, see here. Maybe it might helpful somehow.
You can't exclude the subproject, but you can disable subproject tasks:
gradle.taskGraph.whenReady {
gradle.taskGraph.allTasks.each {
if(it.project == project) {
it.onlyIf { false }
}
}
}
Just to mention that you donćt need to create a new module for integration/functional tests. I prefer to make a new, dedicated source set...
The approach is nicely described here: https://tomgregory.com/gradle-integration-tests/

Gradle: assemble output of a specific configuration

For a project, I have a custom configuration which should simply extend the default one, both in terms of java sources and in terms of dependencies.
This is what it looks like at the moment:
configurations {
// Tools inherits everything from default and adds on
toolsCompile.extendsFrom(compile)
}
sourceSets {
main {
java {
srcDirs = ['src']
}
}
tools {
java {
// Tools extends on the core sources
srcDirs = sourceSets.main.java.srcDirs + ['src-tools']
}
}
}
dependencies {
compile libs.a
compile libs.b
compile libs.c
// Tools adds on the dependencies of the default configuration
toolsCompile libs.d
toolsCompile libs.e
}
I know I could have also used sub-projects for this. I gave up on it, after trying, because I can't get it work properly together with the Eclipse integration plugin (it works fine when used from command line).
I have a couple of questions on the solution above:
Is the way I extend tools.java.srcDirs correct? Is there a more elegant way?
EDIT: Apparently it is not correct, as gradle eclipse generates a .classpath with a duplicate entry for src. Help please?
After I created my tools configuration, I know I can for example use it as a dependency from another project, as in compile project(path: ':myproject', configuration: 'tools'). What do I need to add if I instead want to get the output of the assemble task for my tools configuration? Do I have to make an explicit task for that? The task toolsClasses is created automatically, but not toolsAssemble or toolsBuild.

Resources