I am trying to write Functional test cases using Cucumber. Everything works fine until I try to Autowired any of the Spring Component and use it inside anywhere in Cucumber Test classes.
I am using the below configuration in maven pom.xml
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<cucumber.version>5.1.3</cucumber.version>
</properties>
<dependencies>
<!-- cucumber -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>${cucumber.version}</version>
<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-spring</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<!-- dependency injection -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.4.RELEASE</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>2.2.7.RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
I have the below classes and when I refer the auto wired class inside the step, It is giving NullPointerException in the autowired property.
@Component
public class DataUtil {
public void getData() {
System.out.println( "Extract data ..");
}
}
public class LoadDataToStagingStep {
@Autowired
private DataUtil dataUtil;
@Given("all tables are empty")
public void all_staging_tables_are_empty() {
System.out.println("1");
}
@When("data is loaded")
public void load_data(DataTable table) {
**dataUtil.getData();**
}
@Then("table should have data")
public void data_provided() {
System.out.println("3");
}
}
I have tried to add Context configuration as below, but it is giving different errors and not able to resolve. Can someone help how to make it work cucumber and spring boot autowiring together ?
@SpringBootTest
@AutoConfigureMockMvc
public class CucumberContextConfiguration {
@Before
public void setup_cucumber_spring_context(){
// Dummy method so cucumber will recognize this class as glue
// and use its context configuration.
}
}
The below code is the working structure to use Spring @Autowired in Cucumber Functional test.
CucumberTestContextConfiguration.Java
package com.cucumber.test;
import org.springframework.boot.test.context.SpringBootTest;
import io.cucumber.java.Before;
import io.cucumber.spring.CucumberContextConfiguration;
@CucumberContextConfiguration
@SpringBootTest(classes = TestConfig.class)
public class CucumberTestContextConfiguration {
@Before
public void setup_cucumber_spring_context(){
// Dummy method so cucumber will recognize this class as glue
// and use its context configuration.
}
}
CucumberFunctionalTest.Java
package com.cucumber.test;
import org.junit.runner.RunWith;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
@RunWith(Cucumber.class)
@CucumberOptions(features = "src/test/resources/features",
plugin = {"pretty", "html:target/cucumber/reports"},
glue = {"com.cucumber.test"}
)
public class CucumberFunctionalTest {
}
DataUtil.Java
package com.cucumber.test;
import org.springframework.stereotype.Component;
@Component
public class DataUtil {
public void getData() {
System.out.println( "Extract data ..");
}
}
TestStep.Java
package com.cucumber.test;
import org.springframework.beans.factory.annotation.Autowired;
import io.cucumber.datatable.DataTable;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
public class TestStep {
@Autowired
private DataUtil dataUtil;
@Given("all tables are empty")
public void all_tables_are_empty() {
System.out.println("1");
}
@When("data provided")
public void data_provided(DataTable table) {
dataUtil.getData();
System.out.println("2");
}
@Then("tables are populated with provided data")
public void tables_are_populated_with_provided_data() {
System.out.println("3");
}
}
SpringBootCucumberApplication.Java
package com.cucumber.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@SpringBootApplication
@EnableWebMvc
public class SpringBootCucumberApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootCucumberApplication.class, args);
}
}
test_data.feature
Feature: Test Data Load
Scenario: Verify the Test data
Given all tables are empty
When data provided
Then tables are populated with provided data
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cucumber</groupId>
<artifactId>cucumberdemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<cucumber.version>5.7.0</cucumber.version>
<spring.version>5.2.5.RELEASE</spring.version>
<spring-boot.version>2.2.6.RELEASE</spring-boot.version>
<junit-platform.version>1.6.2</junit-platform.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-core</artifactId>
<version>${cucumber.version}</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>${cucumber.version}</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java8</artifactId>
<version>${cucumber.version}</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-spring</artifactId>
<version>${cucumber.version}</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>${cucumber.version}</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-testng</artifactId>
<version>${cucumber.version}</version>
</dependency>
<!-- Spring doesn't include the right version for surefire to pickup TODO:
Remove once the surefire or spring is upgraded -->
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>