no tests executed after migrating to cucumber 7.x - java

I upgraded recently my Spring Boot project to the latest cucumber-java (7.2.3), and I am facing some issues.
I am able to have the expected behavior, but only by using the now deprecated #Cucumber annotation. the deprecation note says that we should "use the JUnit Platform Suite to run Cucumber"
unfortunately, there are not many examples available (most of them refer to previous versions).
my working code with the deprecated annotation is simply :
package service.test.acceptance;
import io.cucumber.junit.platform.engine.Cucumber;
#Cucumber
public class RunCucumberIntegrationTest {
}
with these dependencies :
testImplementation group: 'io.cucumber', name: 'cucumber-java', version: libraryVersions.cucumber
testImplementation group: 'io.cucumber', name: 'cucumber-junit', version: libraryVersions.cucumber
testImplementation group: 'io.cucumber', name: 'cucumber-spring', version: libraryVersions.cucumber
testImplementation group: 'io.cucumber', name: 'cucumber-junit-platform-engine', version: libraryVersions.cucumber
(and the Junit stuff that comes with Spring Boot Test, so Junit 5.5.2 in my case)
I tried this :
package service.test.acceptance;
import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
import org.junit.platform.suite.api.ConfigurationParameter;
import org.junit.platform.suite.api.IncludeEngines;
import org.junit.platform.suite.api.SelectClasspathResource;
import org.junit.platform.suite.api.Suite;
#Suite
#IncludeEngines("cucumber")
#SelectClasspathResource("service/test/acceptance")
#ConfigurationParameter(key = GLUE_PROPERTY_NAME, value ="service.test.acceptance.integration")
public class RunCucumberIntegrationTest {
}
I needed to add these 2 dependencies so tht it compiled :
testImplementation group: 'org.junit.platform', name: 'junit-platform-suite', version: '1.8.2'
testImplementation group: 'org.junit.platform', name: 'junit-platform-suite-api', version: '1.8.2'
my steps definition are in service.test.acceptance.integration package (in src/test/java), while my feature files are in service/test/acceptance folder (in src/test/resources).
When I run gradlew test, the build is green, but no test gets executed and there's no warning or anything.
any idea of what I am missing ?

Thanks to suggestions by #paul58914080 and #m-p-korstanje , I was able to make it work : thanks a lot !
It was indeed a version incompatibility between the junit and cucumber versions I was using.
This is what I ended up having :
//override the junit version that comes with my version of Spring, and pick one compatible with Cucumber
ext['junit-jupiter.version'] = '5.8.2'
Then in the dependencies block :
testImplementation(platform("io.cucumber:cucumber-bom:7.2.3"))
testImplementation group: 'io.cucumber', name: 'cucumber-java'
testImplementation group: 'io.cucumber', name: 'cucumber-spring'
testImplementation group: 'io.cucumber', name: 'cucumber-junit-platform-engine'
testImplementation group: 'org.junit.platform', name: 'junit-platform-suite'
//this one was already there.. just mentioning it for sake of being exhaustive
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
I didn't need to touch my RunCucumberIntegrationTest class.

Can you try with the following dependencies
pom.xml
<properties>
<junit-jupiter.version>5.8.2</junit-jupiter.version>
<cucumber.version>7.2.3</cucumber.version>
</properties>
....
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-suite</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java8</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit-platform-engine</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-spring</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
RunCucumberExampleTest.java
#Suite
#IncludeEngines("cucumber")
#SelectClasspathResource("features/example.feature")
#ConfigurationParameters({
#ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "packagename.cucumber"),
#ConfigurationParameter(key = FILTER_TAGS_PROPERTY_NAME, value = "#Example"),
#ConfigurationParameter(key = JUNIT_PLATFORM_NAMING_STRATEGY_PROPERTY_NAME, value = "long"),
#ConfigurationParameter(key = PLUGIN_PUBLISH_QUIET_PROPERTY_NAME, value = "true"),
#ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "json:target/cucumber/cucumber.json")
})
public class RunCucumberExampleTest {}
And since you are using spring (and if you are using lambda) you can have a configuration like
SpringCucumberTestConfig.java
#SpringBootTest(classes = ExampleApplication.class, webEnvironment = RANDOM_PORT)
#CucumberContextConfiguration
#ActiveProfiles("test")
public class SpringCucumberTestConfig {}

Related

Can you use spring-boot-starter-test without starter-web?

I'm trying to write integration tests in a separate project that does not have "web" code just tests. I'm trying to only add spring-test-starter like this:
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '2.3.4.RELEASE'
without having to also add this (or a similar starter)
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.3.4.RELEASE'
But it appears that when I go to use
org.springframework.boot.test.web.client.TestRestTemplate
The return type is not included in org.springframework.boot.test it's under "org.springframework.http.ResponseEntity"
public <T> ResponseEntity<T> getForEntity(String url,
Class<T> responseType,
Map<String,?> urlVariables)
throws RestClientException
I can't find anywhere that says that spring-boot-starter-test depends on say spring-boot-starter-web because otherwise what would be the point of the starter? Is there a way to use TestRestTemplate without depending on (2) starters?
If you don't want to use the starter packages, then you need to add dependency for the packages you want manually. Like ResponseEntity is a part of spring-web. So you need to add spring-web dependency to you pom.xml or build.gradle file.
if you only want spring-web for testing, then you can add this line to your build.gradle file.
testCompile group: 'org.springframework', name: 'spring-web', version: '5.2.9.RELEASE'
or your pom.xml file
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.9.RELEASE</version>
<scope>test</scope>
</dependency>
Check the version you need.

SQL Server dependencies in Spring Boot Gradle Java application

I am trying to connect a database to my Spring Boot application using Gradle.
On the internet I only find examples for Maven projects, using the pom.xml file.
I don't know for sure, but I think build.gradle is the equivalent in Gradle? What should I add to it to add support for Microsoft SQL Server?
This is my build.gradle right now:
plugins {
id 'org.springframework.boot' version '2.3.3.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
id 'application'
}
group = 'Project'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
application{
mainClassName 'project.rlstop.Publisher'
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
runtimeOnly 'mysql:mysql-connector-java'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
implementation group: 'org.glassfish.jersey.bundles', name: 'jaxrs-ri', version: '2.+'
implementation group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet', version: '2.+'
// https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api
implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.+'
// https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime
implementation group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '2.+'
// Grizzly will host the service
implementation group: 'org.glassfish.jersey.containers', name: 'jersey-container-grizzly2-http', version: '2.+'
// Logging
implementation group: 'org.slf4j', name: 'slf4j-api', version: '2.+'
implementation group: 'org.slf4j', name: 'slf4j-simple', version: '2.+'
}
test {
useJUnitPlatform()
}
I don't know for sure, but I think build.gradle is the equivalent in Gradle?
Yes, it is. build.gradle is to Gradle what pom.xml is to Maven.
What should I add to it to add support for Microsoft SQL Server?
You currently have a dependency to the MySQL JDBC driver declared:
runtimeOnly 'mysql:mysql-connector-java'
To use MS SQL Server, you need to replace that with
runtimeOnly 'com.microsoft.sqlserver:mssql-jdbc'
You may explorer a skeleton project using the Spring Initializr. You may also refer to the Reference Documentation for instructions on how to configure the data source properties to connect to your MS SQL Server.

Making a cross-platform build of JavaFX using Gradle

I'm working on a new project using Gradle and JavaFX.
I have previously been able to create a cross-platform build using Maven, with the following pom dependencies:
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>13</version>
<classifier>win</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>13</version>
<classifier>linux</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>13</version>
<classifier>mac</classifier>
</dependency>
How do i go about doing something similar with Gradle?
I have tried the following, with no success.
Is the classifier syntax incorrect?
compile group: 'org.openjfx', name: 'javafx-graphics', version: '11.0.2:win'
compile group: 'org.openjfx', name: 'javafx-graphics', version: '11.0.2:linux'
compile group: 'org.openjfx', name: 'javafx-graphics', version: '11.0.2:mac'
Any hints would be greatly appreciated!
The solution turned out to be the following gradle build dependencies:
implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'win'
implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'mac'
implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'linux'
implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'win'
implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'mac'
implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'linux'
implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'win'
implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'mac'
implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'linux'
implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'win'
implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'mac'
implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'linux'
This allows a javafx gradle build to be run on any OS.
The syntax is indeed incorrect in Gradle. Documentation will show you the different supported syntax.
The two most common are the map style you used and the : separated notation.
So taking one of your dependency as an example, you need to use either:
compile group: 'org.openjfx', name: 'javafx-graphics', version: '11.0.2', classifier: 'win'
compile 'org.openjfx:javafx-graphics:11.0.2:win'
Note that you should also stop using the compile configuration and instead use implementation. See this explanation to understand more on this topic.

WARNING: javax.persistence.spi::No valid providers found

I am getting the warning
WARNING: javax.persistence.spi::No valid providers found.
I have code with JPA annotations, but I need them only to use with JOOQ.
How to remove this warning?
Adding my gradle file:
dependencies {
compile project(':common:packages:autogenerated_dao')
externalLib group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: jackson_databind_version
externalLib group: 'javax.validation', name: 'validation-api', version: javax_validation_version
externalLib group: 'org.hibernate', name: 'hibernate-validator', version: hibernate_validator_version
externalLib group: 'javax.el', name: 'javax.el-api', version: javax_el_version
externalLib group: 'org.glassfish', name: 'javax.el', version: glassfish_el_version
externalLib group: 'javax.persistence', name: 'javax.persistence-api', version: javax_persistence_version
}
Mentioned warning raised because javax.persistence-api dependency present in build file, but obviously here is no implementations for it. To get rid from warning, remove javax.persistence-api dependency.
Bean Validation provided by validation-api and its implementation hibernate-validator, so you will be fine.
I was facing same "WARNING: javax.persistence.spi::No valid providers found."
I added below artifact in pom.xml and issue resolved.
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
OR
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>

I can't use #PostConstruct and #PostDestroy with Java 11

I've got problem with using #PostConstruct and#PostDestroy annotations in my project. I can't use these annotations and it looks like these doesn't exist despite the fact that I imported Java's annotations. I am using Java 11 and that is content of my build.gradle file:
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
testCompile group: 'junit', name: 'junit', version: '4.12'
compile group: 'org.springframework', name: 'spring-webmvc', version: '5.1.0.RELEASE'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.7'
compile group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2'
provided group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.1'
}
Note that both #PostConstruct and #PreDestroy annotations are part of Java EE. And since Java EE has been deprecated in Java 9 and removed in Java 11 we have to add an additional dependency to use these annotations:
For Maven
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
If using Gradle
implementation "javax.annotation:javax.annotation-api:1.3.2"
Found here: https://www.baeldung.com/spring-postconstruct-predestroy
You have only spring-webmvc, you need the rest of the spring to be able to use their annotations. Probably spring-core and spring-annotations.
Another solution which worked for me is this.
Go to https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api/1.2
and download the jar file.
Then copy the the jar file to your project lib directory.
Finally point the project build path, under class path to the file you pasted into your local lib folder.

Categories