gauge
gauge copied to clipboard
How to run Spring Boot and Spring Data with Gauge framework
Is your feature request related to a problem? Please describe. Yes, Spring Boot project on Gauge does not work. I'm trying to injection with @Autowired annotation but the injection is not happening. Throwing NullPointerException error.
Describe the solution you'd like When I run the method for db query with Junit, it runs successfully. I specify the annotations below in the class where the method is located. I could not find a similar solution for Gauge.
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class)
Note: Application class is the main class of my project that enables Spring to run.
Describe alternatives you've considered They developed a solution for this situation in the Cucumber framework. A similar solution can be provided. If we cannot solve this problem, unfortunately, we will have to stop using Gauge.
Additional context Hi, In a large e-commerce company in Turkey, test automation structure, we decided to create using the Gauge Framework. We have created a project structure with spring boot and spring data for our DB connections and queries on the Java side. The Spring infrastructure we have created works successfully when run from the java main class. But when we want to run it with the Gauge runner, Spring does not stand up. Do you have a solution for this situation?
Project structure:
- spec
- Payment.spec
- src
- main
- java
- model
- PaymentEntity.java
- repository
- PaymentRepository.java(this class is an interface and extends CrudRepository.java)
- service
- PaymentService.java
- Application.java(main class)
- model
- resources
- application.properties
- java
- test
- java
- payment
- DbCheck.java (I want to perform a db query in this class)
- step
- PaymentStep.java (extends DbCheck.java)
- payment
- java
- main
Content of the DbCheck Class:
package payment;
import Application;
import model.PaymentEntity;
import service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class DbCheck {
@Autowired
private PaymentService paymentService;
@Test
public void checkData() {
List<PaymentEntity> paymentEntity = paymentService.findAllByBankId(100);
System.out.println(paymentEntity.toArray());
}
}
Note: It runs successfully when run with JUnit from @Test annotation.
Thanks, Ahmet
Have you tried using the instructions at https://mesutyakut.medium.com/acceptance-test-with-gauge-and-spring-boot-f675655d8e ?
Yes, I have reviewed this article and the related project. Similarly, when I want to add it to my own project, many exceptions occur in the initialize part and it stays stuck. Spring cannot initialize. Also, there is no DB process in this project. A different project in terms of structure. Some of the exceptions that occur are;
java.lang.UnsupportedOperationException: Reflective setAccessible(true) disabled
at io.grpc.netty.shaded.io.netty.util.internal.ReflectionUtil.trySetAccessible(ReflectionUtil.java:31)
at io.grpc.netty.shaded.io.netty.util.internal.PlatformDependent0$4.run(PlatformDependent0.java:233)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:312)
at io.grpc.netty.shaded.io.netty.util.internal.PlatformDependent0.<clinit>(PlatformDependent0.java:227)
at io.grpc.netty.shaded.io.netty.util.internal.PlatformDependent.isAndroid(PlatformDependent.java:289)
at io.grpc.netty.shaded.io.netty.util.internal.PlatformDependent.<clinit>(PlatformDependent.java:92)
at io.grpc.netty.shaded.io.netty.util.AsciiString.<init>(AsciiString.java:223)
at io.grpc.netty.shaded.io.netty.util.AsciiString.<init>(AsciiString.java:210)
at io.grpc.netty.shaded.io.netty.util.AsciiString.cached(AsciiString.java:1401)
at io.grpc.netty.shaded.io.netty.util.AsciiString.<clinit>(AsciiString.java:48)
at io.grpc.netty.shaded.io.grpc.netty.Utils.<clinit>(Utils.java:72)
at io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder.<clinit>(NettyServerBuilder.java:83)
at com.thoughtworks.gauge.command.StartCommand.execute(StartCommand.java:48)
at com.thoughtworks.gauge.GaugeRuntime.main(GaugeRuntime.java:23)
jdk.internal.misc.Unsafe.allocateUninitializedArray(int): unavailable
java.lang.IllegalAccessException: class io.grpc.netty.shaded.io.netty.util.internal.PlatformDependent0$6 cannot access class jdk.internal.misc.Unsafe (in module java.base) because module java.base does not export jdk.internal.misc to unnamed module @2de23121
at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:385)
at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:693)
at java.base/java.lang.reflect.Method.invoke(Method.java:556)
at io.grpc.netty.shaded.io.netty.util.internal.PlatformDependent0$6.run(PlatformDependent0.java:347)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:312)
at io.grpc.netty.shaded.io.netty.util.internal.PlatformDependent0.<clinit>(PlatformDependent0.java:338)
at io.grpc.netty.shaded.io.netty.util.internal.PlatformDependent.isAndroid(PlatformDependent.java:289)
at io.grpc.netty.shaded.io.netty.util.internal.PlatformDependent.<clinit>(PlatformDependent.java:92)
at io.grpc.netty.shaded.io.netty.util.AsciiString.<init>(AsciiString.java:223)
at io.grpc.netty.shaded.io.netty.util.AsciiString.<init>(AsciiString.java:210)
at io.grpc.netty.shaded.io.netty.util.AsciiString.cached(AsciiString.java:1401)
at io.grpc.netty.shaded.io.netty.util.AsciiString.<clinit>(AsciiString.java:48)
at io.grpc.netty.shaded.io.grpc.netty.Utils.<clinit>(Utils.java:72)
at io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder.<clinit>(NettyServerBuilder.java:83)
at com.thoughtworks.gauge.command.StartCommand.execute(StartCommand.java:48)
at com.thoughtworks.gauge.GaugeRuntime.main(GaugeRuntime.java:23)
java.lang.NullPointerException: Cannot invoke "java.io.File.isDirectory()" because the return value of "org.reflections.vfs.Vfs.getFile(java.net.URL)" is null
at org.reflections.vfs.Vfs$DefaultUrlTypes$3.matches(Vfs.java:233)
at org.reflections.vfs.Vfs.fromURL(Vfs.java:97)
at org.reflections.vfs.Vfs.fromURL(Vfs.java:90)
at org.reflections.Reflections.scan(Reflections.java:236)
at org.reflections.Reflections.scan(Reflections.java:203)
at org.reflections.Reflections.<init>(Reflections.java:128)
at com.thoughtworks.gauge.scan.ClasspathScanner.createReflections(ClasspathScanner.java:58)
at com.thoughtworks.gauge.scan.ClasspathScanner.scan(ClasspathScanner.java:33)
at com.thoughtworks.gauge.connection.MessageProcessorFactory.lambda$new$0(MessageProcessorFactory.java:70)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at java.base/java.lang.Thread.run(Thread.java:832)
19:34:49.458 [pool-1-thread-1] WARN org.reflections.Reflections - could not create Dir using commons_vfs2 from url file:/C:/Program%20Files/Java/jdk-15.0.1!/jdk.javadoc. skipping.
java.lang.NoClassDefFoundError: org/apache/commons/vfs2/VFS
at org.reflections.vfs.Vfs$DefaultUrlTypes$7.matches(Vfs.java:281)
at org.reflections.vfs.Vfs.fromURL(Vfs.java:97)
at org.reflections.vfs.Vfs.fromURL(Vfs.java:90)
at org.reflections.Reflections.scan(Reflections.java:236)
at org.reflections.Reflections.scan(Reflections.java:203)
at org.reflections.Reflections.<init>(Reflections.java:128)
at com.thoughtworks.gauge.scan.ClasspathScanner.createReflections(ClasspathScanner.java:58)
at com.thoughtworks.gauge.scan.ClasspathScanner.scan(ClasspathScanner.java:33)
at com.thoughtworks.gauge.connection.MessageProcessorFactory.lambda$new$0(MessageProcessorFactory.java:70)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at java.base/java.lang.Thread.run(Thread.java:832)
By the way, Spring ran successfully when I tried it with Cucumber. I did the following to make it work;
- Firstly I added the following to the build.gradle file:
implementation 'io.cucumber:cucumber-java:6.9.1' implementation 'io.cucumber:cucumber-spring:6.9.1'
- I use IntellijIDEA as the IDE. I added the following two plugins:
Gherkin Cucumber for Java
- Then I added a feature file for cucumber in the src/test/resources path. (abc.feature)
Feature: Check to run spring with cucumber
Scenario: Try to run spring with cucumber
When Check db with spring
-
Then I created one class and method for the relevant step under src/test/java/glue. (StepDef.java)
-
Then I extended the StepDef class from the DbCheck class.
-
Then I added @CucumberContextConfiguration and @SpringBootTest (classes = Application.class) annotations to the StepDef class.
package glue;
import Application
import io.cucumber.java.en.When;
import io.cucumber.spring.CucumberContextConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import payment.DbCheck;
@CucumberContextConfiguration
@SpringBootTest(classes = Application.class)
public class StepDef extends DbCheck{
@When("Check db with spring")
public void checkDb() {
checkData();
}
}
- I rearranged the DbCheck.java class as follows:
package payment;
import model.PaymentEntity;
import service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
@Slf4j
public class DbCheck {
@Autowired
private PaymentService paymentService;
public void checkData() {
List<PaymentEntity> paymentEntity = paymentService.findAllByBankId(100);
System.out.println(Arrays.toString(paymentEntity.toArray()));
}
}
- When I ran the test from the abc.feature file, it ran successfully.
Is a similar method of use possible with Gauge?
Hi @AhmetRufai , I'm investigating the same issue now, did you manage to find a way to make it working?
Hi @0vid1u, Unfortunately, we couldn't find a solution as we wanted. We had to continue automation with the Cucumber tool.
@AhmetRufai @0vid1u - sorry to hear this didn't work. I am not familiar with Spring Boot, and there's a good chance that gauge-java may need some tweaking to get this working.
I can work on this, but I'd need a sample project where I can see this issue.
I have Spring Framework working with gauge (1.4.0 / Gauge-java 0.7.15) perfectly with version 5.2.4.RELEASE. however, upgrading to newest version is causing the issue noted here. i will try to investigate further... Hopefully, can get it to work.
Could you please share working example with older release. We can try to investigate it and interested to make it works. Thanks
These errors are usually related to logback with gauge.
I had to exclude all 1.2.* versions and replace with:
xml <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.3.0-alpha5</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.3.0-alpha5</version> </dependency>