UnknownClass.Cucumber while running JUnit engine + Cucumber + Gradle tests from command line - build.gradle

Me and my team just moved from JUnit4 to JUnit5 and we faced with parallelism issues. With 4th version we used -Dcucumber.options="--threads 5" to run in tests several threads, but after deprecation and removing of cucumber options it's obviously doesn't work anymore. I set up (at least I think so) junit platform engine for the project (https://github.com/cucumber/cucumber-jvm/tree/main/cucumber-junit-platform-engine#configuration-options), but when I try to run tests via comand line (using Gradle task), I receive following error:
UnknownClass.Cucumber > UnknownClass.initializationError FAILED
org.junit.platform.commons.JUnitException at EngineExecutionOrchestrator.java:114
Caused by: org.junit.platform.commons.JUnitException at HierarchicalTestEngine.java:57
Caused by: org.junit.platform.commons.JUnitException at DefaultParallelExecutionConfigurationStrategy.java:41
Unfortunately, didn't find something in the internet, maybe someone can help with it?
What we use:
Spring boot 2.7.3
Gradle 7.5.1
Cucumber java, junit, spring, junit-platform-engine 5.7.0
junit-platform-suite-api 1.3.2
Tasks in build.gradle that I have now:
useJUnitPlatform()
systemProperty("cucumber.junit-platform.naming-strategy", "long")
systemProperty("cucumber.execution.parallel.enabled", true)
systemProperty("cucumber.execution.parallel.config.strategy", "fixed")
systemProperty("cucumber.plugin", "html:reports/html")
systemProperty("cucumber.plugin", "pretty")
systemProperty("cucumber.plugin", "junit:reports/junit")
doLast {
javaexec {
mainClass.set("io.cucumber.core.cli.Main")
classpath = cucumberRuntime + sourceSets.test.get().output + sourceSets.main.get().output
}
}
}
tasks {
val consoleLauncherTest by registering(JavaExec::class) {
dependsOn(testClasses)
val reportsDir = file("$buildDir/test-results")
outputs.dir(reportsDir)
classpath = sourceSets["test"].runtimeClasspath
mainClass.set("org.junit.platform.console.ConsoleLauncher")
args("--scan-classpath")
args("--include-engine", "cucumber")
args("--reports-dir", reportsDir)
}
test {
dependsOn(consoleLauncherTest)
exclude("**/*")
}
}
Configuration class:
#CucumberContextConfiguration
#Suite
#IncludeEngines("cucumber")
#SelectClasspathResource("com/example")
#ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.example")
#SpringBootTest
#ContextConfiguration(classes = [IntegrationContext::class], loader = SpringBootContextLoader::class)
class Application() {}

Your question is pretty much impossible to answer because you didn't go through the process of making a minimal reproducer. For your next question please read the "Help others reproduce the problem" section in How do I ask a good question?.
With 4th version we used -Dcucumber.options="--threads 5" to run in tests several threads, but after deprecation and removing of cucumber options it's obviously doesn't work anymore.
Project typically include a CHANGELOG and release notes documenting all relevant changes.
What we use:
Spring boot 2.7.3
Cucumber java, junit, spring, junit-platform-engine 5.7.0
junit-platform-suite-api 1.3.2
These dependencies don't converge and aren't quite correct. You'll want to use Cucumber's and JUnit's Bill of Materials to avoid having to specify the version for every module.
If you're using Spring Boot in the recommended way you may also be able to omit the junit-bom altogether.
dependencies {
testImplementation(platform("org.junit:junit-bom:5.9.1"))
testImplementation(platform("io.cucumber:cucumber-bom:7.9.0"))
testImplementation("io.cucumber:cucumber-java")
testImplementation("io.cucumber:cucumber-junit-platform-engine")
testImplementation("org.junit.platform:junit-platform-suite")
testImplementation("org.junit.jupiter:junit-jupiter")
}
Tasks in build.gradle that I have now:
So in this build file it appears that you are trying to run Cucumber in 3 different ways. Through the JUnit Platform, through Cucumbers CLI and through the JUnit 5 ConsoleLauncher.
I don't know which solution you are trying use but suppose that you want to use the JUnit Platform, then you look at cucumber-java-skeleton for a working example.
Then afterwards you should clean up your build file. :D

Related

How to configure bootBuildImage task to be up-to-date when no changes to source code

I'm trying to use spring boot 2.3's new support for creating docker images, but the bootBuildImage gradle task is never up-to-date. This unfortunately causes a new docker image to be generated even if no source code was changed.
My goal is to have a static build command that doesn't result in new images being produced unnecessarily. So something like one of the two scenarios below:
./gradlew bootBuildImage (but does nothing if no source code has changed)
OR
./gradlew someOtherTask (if this task is not up-to-date, it triggers bootBuildImage)
My latest effort was to configure bootBuildImage to only run if the bootJar task is not up to date:
tasks {
val bootJarTask: TaskProvider<BootJar> = this.bootJar
bootBuildImage {
outputs.upToDateWhen {
bootJarTask.get().state.upToDate
}
}
}
But this fails with this error (for some reason this particular task hates jars as inputs)
> Unable to store input properties for task ':bootBuildImage'. Property 'jar' with value '/demo/build/libs/demo-0.0.1-SNAPSHOT.jar' cannot be serialized.
Surely I'm missing something obvious here! The reason I need bootBuildImage to only produce an image when necessary is because I've got a multi-project build. I don't want subprojects to generate and push a new image even when nothing in them changed.
Using Spring Boot 2.3.4, Gradle 6.6.1, Java 11.
This seems to work:
val bootJarTask: TaskProvider<BootJar> = this.bootJar
bootBuildImage {
onlyIf {
!bootJarTask.get().state.skipped
}
}

Can the ConfigurationAPI in Liferay DXP be used for Plugin sdk portlet?

I have followed given 2 tutorials to use COnfigurationAPI in a Liferay dxp plugins SDK portlet built using Ant/Ivy.
COnfiguration API 1
COnfiguration API 2.
Below is the configuration class used:
package com.preferences.interfaces;
import com.liferay.portal.configuration.metatype.annotations.ExtendedObjectClassDefinition;
import aQute.bnd.annotation.metatype.Meta;
#ExtendedObjectClassDefinition(
category = "preferences",
scope = ExtendedObjectClassDefinition.Scope.GROUP
)
#Meta.OCD(
id = "com.preferences.interfaces.UnsupportedBrowserGroupServiceConfiguration",
name = "UnsupportedBrowser.group.service.configuration.name"
)
public interface UnsupportedBrowserGroupServiceConfiguration {
#Meta.AD(deflt = "", required = false)
public String displayStyle();
#Meta.AD(deflt = "0", required = false)
public long displayStyleGroupId(long defaultDisplayStyleGroupId);
}
Post following the steps,I am getting the below error:
ERROR [CM Configuration Updater (ManagedService Update: pid=[com.preferences.interfaces.UnsupportedBrowserGroupServiceConfiguration])][org_apache_felix_configadmin:97] [org.osgi.service.cm.ManagedService, id=7082, bundle=297//com.liferay.portal.configuration.settings-2.0.15.jar?lpkgPath=C:\dev\Liferay\osgi\marketplace\Liferay Foundation.lpkg]: Unexpected problem updating configuration com.preferences.interfaces.UnsupportedBrowserGroupServiceConfiguration {org.osgi.service.cm.ConfigurationAdmin}={service.vendor=Apache Software Foundation, service.pid=org.apache.felix.cm.ConfigurationAdmin, service.description=Configuration Admin Service Specification 1.2 Implementation, service.id=56, service.bundleid=643, service.scope=bundle}
Caused by: java.lang.IllegalArgumentException: wrong number of arguments
So,does this process need a osgi module as mandatory or can we do it using plusings sdk portlet built using ant as well?
Without disecting the error message Caused by: java.lang.IllegalArgumentException: wrong number of arguments:
The way you build your plugin (Ant, Maven, Gradle, manually) doesn't make a difference, as long as you build a plugin that will be understood by the runtime. aQute.bnd.annotation.metatype.Meta points firmly into the OSGi world, and makes it almost certain that you'll need an OSGi module. You can build this with Ant, of course. Even in Ant you can embed tools like bnd, or you can write the proper Manifest.mf to include in your module manually (just kidding - you don't want to do it manually, but it would work).
Recommendation: Instead of moving everything over: Try to reproduce this with a minimal example in gradle or better Liferay Workspace (which is gradle based), just to get all the automatic wiring in. Check if it makes a difference and compare the generated output from your Ant build process with the workspace output. Pay specific attention to the Manifest.
In order to build the proper Manifest, you want to use bnd - if the Manifest turns out to be your issue: Find a way to embrace bnd - if that's by saying goodby to Ant, or by tweaking your build script remains your decision.

Sonar Unit tests report parameter - sonar.junit.reportPath vs sonar.java.junit.reportPath

I found that my Sonar instance 5.1 or 5.1.1 (with latest sonar-runner 2.x) stopped showing part of the Unit test info (Unit test widget) on the project's dashboard.
The properties I had were (in Gradle's sonarRunner > sonarProperties section):
property "sonar.junit.reportsPath", "build/test-results/UT"
property "sonar.surefire.reportsPath", "build/test-results/UT"
To fix it, I had to include the following properties as well:
property "sonar.java.junit.reportsPath", "build/test-results/UT"
property "sonar.java.surefire.reportsPath", "build/test-results/UT"
Just FYI: All my Unit tests reports go under build/test-results/UT folder, all Integration Tests result files go unedr build/test-results/IT folder and etc.
I'm wondering if this is due to Gradle version that I'm using (2.3) or is it due to a later version of SonarQube (4.5+) as I have both SQ 5.1 and 5.1.1 instance.
I know SonarQube team started Multi language support since SonarQube version 4.12
Since SonarQube 4.2, it is possible to run an analysis on a multi-language project.
Now, it raises a question. For Getting the same Unit test info for Groovy based projects, do I need to use:
property "sonar.groovy.junit.reportsPath", "build/test-results/UT"
property "sonar.groovy.surefire.reportsPath", "build/test-results/UT"
something like that if my project has Groovy code instead of java?
Searching "**sonar.java.junit.reportPath"** with using double quotes shows No results found in Google and it forces me to try and see google results if I can run the search again without using " double quotes (for this property).
Doing the same in SonarQube site "search box" shows:
No results found for sonar.java.junit.reportPath. Please try one of the following suggestions:
Though in Gradle, inside
sonarRunner task {
.. inside ..
sonarProperties {
... section ... where I define various sonar props..
}
...
}
I can define both sonar.junit.reportPath, sonar.java.junit.reportPath and similarly, sonar.surefire.reporPath and sonar.java.surefire.reportPath and while running sonarRunner task in Gradle, it doesn't error out. Thus it makes me believe that the property variables are valid.
There are also issues with running sonarRunner or stand alone sonar-runner command for a mixed Java and Groovy based project (i.e. source code in Java but tests in Groovy). Setting sonar.language=java,grvy didn't help. I posted this question on stackoverflow but so far I have no perfect result/answer on how to get a full fledged sonar dashboard up and running for a Groovy projects like I get for a Java project.
Groovy project - Sonar - Publish project and Unit + Integration Test code coverage data
PS: I have tried various values for setting sonar.. variables (as far a sonar source, tests, etc, etc properties are concerned, which they have mentioned on their site's docs section)
The only valid property to use as of now is sonar.junit.reportsPath which will tell the java sonarqube plugin where to import your result of unit tests.
For groovy, this is work in progress, see : http://jira.sonarsource.com/browse/SONARGROOV-2
All the other properties you mentioned do not exist and are not taken into account.

Want to use JUnit in Domino Designer / Java Beans - but keep getting a "Class not found" error?

I do the following:
From the Package Explorer I select "New, Other, JUnit Test Case"
I write this code:
package dk.sample;
import org.junit.*;
import static org.junit.Assert.*;
public class TestCase {
#Test
public void alwaysTrue(){
assertTrue( true );
}
}
I then select "Run As, JUnit test"
Get this error: "Class not found dk.sample.TestCase
java.lang.ClassNotFoundException: ...."
What do I miss? Have tried with different Run Configurations - but it seems like I miss a classpath somewhere? But to what and where?
To make JUnit work within Domino Designer you need to perform few additional steps:
set up source control for your application
adjust the on-disk project to be recognized as Java application
run JUnit tests within your on-disk project
Please note that java agents have to be tested in a different way..
You can find more detailed explanation about enabling JUnit for both XPages and Agents in the following blog post: Unit Tests for Lotus Domino Applications
Here's also a great how-to on this topic.
Coundn't get JUnit to work inside the Domino Designer. Instead of running the tests from DDE, I now run the tests from a XPages. This works like a dream. Made my own 'JUnit runner' class - that is, I just call the JUnit runners but handles the result my self in order to display it as html on the XPage.
Code can be found here: http://xpages.dk/wp-content/uploads/2013/10/junitrunner.txt
Danish blog post here: http://xpages.dk/?p=1162

Eclipse RCP: Using different JUnit version (4.3.1) than shipped with eclipse galileo (4.5.0)

Hallo,
I have the following situation:
We are developing an Eclipse RCP Application and want to switch from Eclipse 3.4 to Eclipse 3.5. Our JUnit-Tests are using JUnit 4.3.1 and we have a launch configuration to start our test suite. I think I don't need to go into more details here.
The problem is:
Running the tests with Eclipse 3.5 does not work: JUnit cannot find any annotations in the test classes (neither (at)Test nor (at)RunWith).
I patched the junit library with some logging output to check what is going on. I found out that this problem is a classloading issue:
The test class passed to JUnit 'lies in' a ClassLoader which is different from the one JUnit uses to load the annotation classes like 'RunWith'. This is not the case in Eclipse 3.4
in org.junit.internal.requests.ClassRequest:
public Runner getRunner() {
log("TestClass ClassLoader: "+this.fTestClass.getClassLoader());
log("RunWith.class ClassLoader: "+RunWith.class.getClassLoader());
... // validating test class: searching for annotations and more
}
The first line prints another classloader than the second line. This is bad because JUnit cannot match the annotations in the test class with the Annotation-Class (here: RunWith.class): "RunWith" in CL1 is not equal to "RunWith" in CL2.
I have a solution which points to the core problem: Replace JUnit 4.5 in Eclipse Galileo with JUnit 4.3.1 so that there is only one JUnit-Version: The Test-Run and the tests classes are both using JUnit 4.3.1 (I had to patch "org.eclipse.jdt.junit4.runtime" to accept an ealier junit version).
I think I can also replace JUnit 4.3.1 in my test class with Version 4.5, but that is not an option yet.
Guess: The classloaders are different because the classes 'come from' different JUnit-Bundles: the testclass with its annotations from version 4.3.1 and the test runs in version 4.5
What I want to know: Is there any other solution besides patching Eclipse (replace JUnit versions)? Any commandline argument or such? Any configuration to force Eclipse to Use JUnit 4.3.1?
Any hints on the above described analysis are welcome!
I'm not sure that's what you're looking for but:
In the Run Configuration of your JUnit tests, you can choose the Test Runner you want to use (JUnit 4, JUnit 3...)