Cucumber with Spring Config doesnt work, can't run tests: io.cucumber.core.backend.CucumberBackendException: Please annotate a glue class - spring

im trying to setup a cucumber with spring project to use autowiring and spring config options (application.yml). Now that i created a runner class to pass parameters from outside executing runs on following exception:
Weird is, i have a class exactly with the proposed annotations, so i guess it's not found and something on the project structure is off, but i don't get what exactly.
Here is my project structure:
src.main.java.package.config.SpringConfig.java
src.main.java.package.steps.StepsSpringConfig.java
src.test.java.package.runner.CucumberRunner.java
SpringConfig.java
#ComponentScan("package")
#EnableConfigurationProperties{PropertyClasses}
StepsSpringConfig.java
#SpringBootTest(classes = SpringConfig.class)
#CucumberContextConfiguration
All Step classes extend from this class
CucumberRunner.java
#RunWith(Cucumber.class)
#CucumberOptions(steps = path/to/features, glue = {src.package.steps, src.package.config})
In my JUnit RunConfig I use this runner class
When i run i get the error on the screenshot above. What am i missing?
Im using the latest version of IntelliJ (2021.2.2)
Im using Spring 2.3.12 and cucumber-junit 6.8.0

Ok im dumb, the solution is found here: Cucumber options annotation
i specified the glue path like "src.main.java.package.steps" but it needs to be just "package.steps" and it works fine

Related

Cucumber configuration error in IntelliJ: Please annotate a glue class with some context configuration

So I recently started working on Cucumber and have been facing this issue.
This is the hierarchy of my module
As you can see this is submodule in my Spring Boot application (AcceptanceTests), so there are no main methods in it.
This is my CucumberSpringContextConfiguration class
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#CucumberContextConfiguration
public class CucumberSpringContextConfiguration {
}
This is my CucumberIntegrationTest class
#RunWith(Cucumber.class)
#CucumberOptions(
features = "src\test\resources\feature",
plugin = {"pretty", "html:target\\cucumber"},
glue = "com.#####.########.cucumberspringboot.cucumberglue"
)
public class CucumberIntegrationTest {}
I tried running this code with a main class (src/main/java),the code compiled successfully. But since that is not my requirement I removed it and now I am getting below error -
SEVERE: Exception while executing pickle
java.util.concurrent.ExecutionException:
io.cucumber.core.backend.CucumberBackendException: Please annotate a
glue class with some context configuration.
For example:
#CucumberContextConfiguration
#SpringBootTest(classes = TestConfig.class)
public class CucumberSpringConfiguration { }
Or:
#CucumberContextConfiguration
#ContextConfiguration( ... )
public class CucumberSpringConfiguration { }
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at io.cucumber.core.runtime.Runtime.run(Runtime.java:93)
at io.cucumber.core.cli.Main.run(Main.java:92)
at io.cucumber.core.cli.Main.main(Main.java:34)
Caused by: io.cucumber.core.backend.CucumberBackendException:
Please annotate a glue class with some context configuration.
Please suggest how to achieve this without using main class.
io.cucumber.core.cli.Main.run(Main.java:92) at io.cucumber.core.cli.Main.main(Main.java:34)
This part of the stacktrace shows you are using the Cucumber CLI rather than CucumberIntegrationTest. So you are probably running your feature file through IDEA. Presumably you clicked the green play icon in the gutter of a feature file.
Unfortunately Intelij IDEA makes some assumptions and bad guesses. If you look at the run configuration that was created you'll see that there is a command line with --glue argument that probably points at features. You'll have to change this manually.
It is currently unnecessary to guess the --glue argument and I have already asked the team behind Intelij IDEA to fix this at IDEA-243074 but the issue has gotten zero attention so far. You can upvote it, maybe something happens.
You can also avoid this problem by putting your feature files in a different location e.g. src/test/resources/com/#####/########/cucumberspringboot. Becaus this is the parent package of cucumberglue Ingelij IDEA is less likely to mess things up.
Also note: you are currently using JUnit 4 to run Cucumber. Spring Boot prefers using JUnit 5. You should use the Cucumber JUnit Platform Engine. You can find a minimal example here.

I can't import the containsString CoreMatcher from hamcrest

I'm trying to do the following:
import static org.hamcrest.CoreMatchers.containsString
assertThat(myvar, containsString("string to check"))
Here are my dependencies. I need to support junit 4 and junit 5
testCompile('org.mockito:mockito-all:+')
testCompile('org.mockito:mockito-inline:+')
// use junpiter
testImplementation(platform('org.junit:junit-bom:+'))
testImplementation('org.junit.jupiter:junit-jupiter')
testImplementation('org.junit.jupiter:junit-jupiter-params')
// AND junit 4 because I use a test framework that has a hard dependency on junit 4
testImplementation("junit:junit:4.13")
testRuntimeOnly("org.junit.vintage:junit-vintage-engine:5.7.2")
// Trying to pull in latest hamcrest
testImplementation('org.hamcrest:hamcrest:2.2')
The problem is in my class when I to import static org.hamcrest.CoreMatchers.containsString It appears to be using hamcrest 1.3 which does not have "containsString". Is it using 1.3 because junit 4 depends on this version of hamcrest?
Is what I'm trying to do impossible because I'm pulling in both junit 4 and jupiter?
EDIT
In my editor it says it does not exist:
Using my IDE I can read its docs on my localhost: (http://localhost:63342/..../hamcrest-core-1.3-javadoc.jar/org/hamcrest/CoreMatchers.html)
When trying to run it I get this error
No signature of method: src.myproject.MyClassTest.containsString() is applicable for argument types: (String) values: [string to check]
groovy.lang.MissingMethodException: No signature of method: src.myproject.MyClassTest.containsString() ....
Per comments I can see now it looks like its using CoreMatchers from mockito for some reason:
EDIT Solution
Per comments the issue was that CoreMatchers was coming from mockito. I have removed mockito as a dependency and deleted its jars and that fixed it.
But I still don't understand how/why this was happening. I hope a proper answer to my question will include an explanation of why CoreMatchers was being fetched from the wrong place.

Trouble using a base Spock Specification and JenkinsRule with PluginManager

I want to use different sets of plugins for different Spock Specifications that extend an abstract BaseSpecification. I am having trouble doing that. From what I read, the #WithPlugin annotation didn't quite seem like what I need. So I've been trying to use JenkinsRule.with(PluginManager).
I'm using the Groovy Spock framework and v2.59 of the Jenkins Unit Test Harness org.jenkins-ci.main:jenkins-test-harness:2.59 to test Jenkins Job DSL that we've written to automate the initialization of our Jenkins instances.
I have a BaseSpecification class where I declare a field #Shared #ClassRule jenkinsRule = new JenkinsRule(). As I understand it, the JenkinsRule is how we interact with the Jenkins Unit Test Harness and the embedded Jenkins instances. This has worked fine in the past for all Specifications that extend BaseSpecification and define their own feature methods.
But when I try to use something like #Shared #ClassRule jenkinsRule = new JenkinsRule().with(getPluginManager()), in the abstract BaseSpecification—where abstract JenkinsRule getPluginManager() is declared—if I return MyPluginManager.INSTANCE for some specs but not others, I keep getting the following error:
class org.jenkinsci.plugins.workflow.job.WorkflowJob is missing its descriptor
java.lang.AssertionError: class org.jenkinsci.plugins.workflow.job.WorkflowJob is missing its descriptor
at jenkins.model.Jenkins.getDescriptorOrDie(Jenkins.java:1600)
at org.jenkinsci.plugins.workflow.job.WorkflowJob.getDescriptor(WorkflowJob.java:421)
at hudson.model.ItemGroupMixIn.createProjectFromXML(ItemGroupMixIn.java:285)
at jenkins.model.Jenkins.createProjectFromXML(Jenkins.java:3989)
at javaposse.jobdsl.plugin.JenkinsJobManagement.createNewItem(JenkinsJobManagement.java:517)
at javaposse.jobdsl.plugin.JenkinsJobManagement.createOrUpdateConfig(JenkinsJobManagement.java:141)
at javaposse.jobdsl.dsl.AbstractDslScriptLoader.extractGeneratedJobs_closure4(AbstractDslScriptLoader.groovy:204)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:430)
at javaposse.jobdsl.dsl.AbstractDslScriptLoader.extractGeneratedJobs(AbstractDslScriptLoader.groovy:197)
at javaposse.jobdsl.dsl.AbstractDslScriptLoader.extractGeneratedItems(AbstractDslScriptLoader.groovy:184)
at javaposse.jobdsl.dsl.AbstractDslScriptLoader.runScripts_closure1(AbstractDslScriptLoader.groovy:63)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:430)
at javaposse.jobdsl.dsl.AbstractDslScriptLoader.runScripts(AbstractDslScriptLoader.groovy:46)
at BaseJobScriptsSpec.generateDslItems(BaseJobScriptsSpec.groovy:241)
at BaseJobScriptsSpec.setupSpec(BaseJobScriptsSpec.groovy:38)
It seems like whichever PluginManager is used first changes state somewhere, either in a temporary file directory or elsewhere, that causes the error on the next test that uses a JenkinsRule with a different PluginManager. As it is now MyPluginManager is just a copy/paste of org.jvnet.hudson.test.TestPluginManager while I get this proof of concept to work.
What am I doing wrong here? Thank you.
EDIT 2021-08-04 Adding link to repo with reproduced error:
https://github.com/matthiasdenu/plugin-manager-bug/blob/main/src/test/groovy/CustomPluginMangerSpecification.groovy#L12

Can't find #SpringBootApplication from JUnit test file

I was following the guide here, https://spring.io/guides/gs/spring-boot/ - cloned the project, built with Gradle and tried to run...application ran fine. Then I changed some file structure as per my requirement and tried to run the unit test case given there, but getting this error -
Unable to find a #SpringBootConfiguration, you need to use #ContextConfiguration or #SpringBootTest(classes=...) with your test
I only restructure the codes in there, and this is my current project structure -
/projectroot
- /src/main/java
-Application.java
-/controller
-MyController.java
-/util
-MyUtil.java
-/model
-MyModel.java
Now trying to run test case from
/src/test/java/controller/MyControllerTest.java
I have gone through this Stack Overflow link and understood that if I put my test folder under /src/main/java/ it may work. But if I do that test file doesn't compile and it also doesn't seem the right way to put application code along with test code. I know I'm missing something very fundamental.
The way you setup your test (using the whole spring boot context), I believe MyControllerTest.java needs to be at most at the same level as Application.java. Also, I notice Application.java is using default package, you should move it into a package, so that all your beans are below your Spring Boot main class:
/projectroot
- /src/main/java/com/example/project/
-Application.java
-/controller
-MyController.java
-/util
-MyUtil.java
-/model
-MyModel.java
- /src/test/java/com/example/project/
-MyControllerTest.java
Spring's documentation
How Spring Boot's context is resolved from a test:
The search algorithm works up from the package that contains the test
until it finds a #SpringBootApplication or #SpringBootConfiguration
annotated class. As long as you’ve structure your code in a sensible
way your main configuration is usually found.
About using the default package with Spring Boot:
When a class doesn’t include a package declaration it is considered to
be in the “default package”. The use of the “default package” is
generally discouraged, and should be avoided. It can cause particular
problems for Spring Boot applications that use #ComponentScan,
#EntityScan or #SpringBootApplication annotations, since every class
from every jar, will be read.
We recommend that you follow Java’s recommended package naming conventions and use a reversed domain name (for example, com.example.project).

spring 3.x issue of no such method error

Hi i am using spring framework and while executing annotationbased test case i am getting error can any one have idea about which jar dependancy(maven artifact) file do i need to add in my pom.xml ?
org.springframework.transaction.interceptor.TransactionAttribute.getQualifier() no such method error
Looks like you have two incompatible jars.
Check that: spring-tx and spring-test is of the same version (3.0.x).
If this does not help. Place a break point at TransactionalTestExecutionListener and check that the concreate class that implements TransactionAttribute is of correct version too.

Resources