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