Practice Behavior Driven Development (BDD) with Cucumber and Spring

    Introduction to BDDTBD

Build and start the service under test

    This article uses the Rest Service in Spring Getting Started, https://spring.io/guides/gs/rest-service/ , readers can try to build and start it by themselves. After the startup is successful, visit http://localhost:8080/greeting?name=User in the browser and receive the response {"id":1,"content":"Hello, User!"}

Create project skeleton

    Create a Spring Boot project, add Cucumber to pom.xml, and integrate dependencies with JUnit and Spring:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
	<groupId>io.cucumber</groupId>
	<artifactId>cucumber-java8</artifactId>
	<version>3.0.2</version>
	<scope>test</scope>
</dependency>

<dependency>
	<groupId>io.cucumber</groupId>
	<artifactId>cucumber-spring</artifactId>
	<version>3.0.2</version>
	<scope>test</scope>
</dependency>

<dependency>
	<groupId>io.cucumber</groupId>
	<artifactId>cucumber-junit</artifactId>
	<version>3.0.2</version>
	<scope>test</scope>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-test</artifactId>
	<scope>test</scope>
</dependency>

Define Cucumber Steps

    First, create a new class in the test source directory src/test/java of the project, and add Cucumber executor and configuration annotations:

@RunWith(Cucumber.class)
@CucumberOptions(features = "classpath:features/")
public class CucumberSpringClientApplicationTests {

}

    Create a new features folder in the test resource directory src/test/resource of the project, and place feature files in it, such as rest-test.feature

Feature: the greeting msg can be retrieved
  Scenario: client makes call to GET /greeting
    Given name is "User"
    When the client calls /greeting
    Then the client receives status code of 200
    And the client receives content "Hello, User!"

Implement Cucumber Steps

    Execute CucumberSpringClientApplicationTests in JUnit mode, and you can see the prompt to implement the Cucumber step definition in the console:

You can implement missing steps with the snippets below:

Given("name is {string}", (String string) -> {
    // Write code here that turns the phrase above into concrete actions
    throw new PendingException();
});
……

    Define a class that implements the cucumber.api.java8.En interface, and implement the Cucumber Steps prompted in its constructor. The implementation of this example is as follows:

public class FooStepDefinition implements En {

	String name;

	ResponseEntity<GreetingDTO> response;

	public FooStepDefinition() {
		Given("name is {string}", (String name) -> {
			this.name = name;
		});

		When("the client calls \\/greeting", () -> {
			response = new RestTemplate().getForEntity("http://localhost:8080/greeting?name=" + name,
					GreetingDTO.class);
		});

		Then("the client receives status code of {int}", (Integer statusCode) -> {
			Assert.assertEquals(statusCode.intValue(), response.getStatusCodeValue());
		});

		Then("the client receives content {string}", (String greeting) -> {
			Assert.assertEquals(greeting, response.getBody().getContent());
		});
	}
}

Execute Cucumber tests

    Execute CucumberSpringClientApplicationTests in JUnit mode, and you can see that the Cucumber test is executed successfully:

Combining the capabilities of Spring Boot

    Let's try the capabilities of Spring Boot, put url=http://localhost:8080 into the src/test/resouces/application.properties file, and try to transform FooStepDefinition to get it from the configuration file:

public class FooStepDefinition implements En {

	@Value("${url}")
	String url;

	public FooStepDefinition() {
		When("the client calls \\/greeting", () -> {
			response = new RestTemplate().getForEntity(url + "/greeting?name=" + name, GreetingDTO.class);
		});

    During execution, it was found that the URL could not be obtained. After viewing reference 3, it was found that adding a @SpringBootTest to the class can solve this problem:

@SpringBootTest(classes = CucumberSpringApplicationTests.class)
public class FooStepDefinition implements En {

Source code gift

    The source code used in this article can be downloaded from Gitee: https://gitee.com/gongxusheng/cucumber-spring

References

1. http://www.baeldung.com/cucumber-spring-integration

2. https://docs.cucumber.io/cucumber/step-definitions/

3. https://github.com/cucumber/cucumber-jvm/tree/master/spring

Guess you like

Origin blog.csdn.net/gongxsh00/article/details/81103126