使用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集成的依賴:

<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>

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

執行Cucumber測試

    以JUnit方式執行CucumberSpringClientApplicationTests,可以看到Cucumber測試執行成功:

結合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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章