使用Cucumber和Spring实践行为驱动开发(BDD)

    BDD简介 TBD

搭建并启动被测服务

    本文使用了Spring Getting Started中的Rest Service,https://spring.io/guides/gs/rest-service/,读者可以自行尝试搭建并启动。启动成功以后,在浏览器中访问http://localhost:8080/greeting?name=User,收到响应{"id":1,"content":"Hello, User!"}

创建项目骨架

    创建一个Spring Boot项目,在pom.xml中加入Cucumber,以及和JUnit、Spring集成的依赖:


	org.springframework.boot
	spring-boot-starter-web



	io.cucumber
	cucumber-java8
	3.0.2
	test



	io.cucumber
	cucumber-spring
	3.0.2
	test



	io.cucumber
	cucumber-junit
	3.0.2
	test



	org.springframework.boot
	spring-boot-starter-test
	test

定义Cucumber Steps

    首先在项目的测试源码目录src/test/java中新建一个类,添加Cucumber执行器和配置的注解:

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

}

    在项目的测试资源目录src/test/resource中新建一个features文件夹,在其中放置feature文件,如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!"

实现Cucumber Steps

    以JUnit方式执行CucumberSpringClientApplicationTests,可在控制台中看到实现Cucumber步骤定义的提示:

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();
});
……

    定义一个实现cucumber.api.java8.En接口的类,在其构造构造函数中实现提示的Cucumber Steps,本例的实现如下:

public class FooStepDefinition implements En {

	String name;

	ResponseEntity 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());
		});
	}
}

执行Cucumber测试

    以JUnit方式执行CucumberSpringClientApplicationTests,可以看到Cucumber测试执行成功:

使用Cucumber和Spring实践行为驱动开发(BDD)_第1张图片

结合Spring Boot的能力

    下面尝试一下Spring Boot的能力,将url=http://localhost:8080放入src/test/resouces/application.properties文件中,尝试将FooStepDefinition改造为从配置文件中获取:

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);
		});

    执行时却发现无法获得URL,查看参考资料3以后,发现在类上增加一个@SpringBootTest可以解决这个问题:

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

源码奉送

    本文使用的源代码可以在Gitee下载:https://gitee.com/gongxusheng/cucumber-spring

参考资料

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

你可能感兴趣的:(实用技术)