1. Overview
1.概述
In this short tutorial, we’re going to learn about Cucumber Backgrounds, which is a feature that allows us to execute some sentences for each test of a Cucumber Feature.
在这个简短的教程中,我们将学习Cucumber Backgrounds,这是一个允许我们为Cucumber Feature的每个测试执行一些句子的功能。
2. Cucumber Background
2.黄瓜背景
First, let’s explain what the Cucumber Background is. Its purpose is to execute one or more sentences before each test of a feature.
首先,我们来解释一下什么是黄瓜背景。它的目的是在每次测试某个功能之前执行一个或多个句子。
But what problem are we trying to solve here?
但我们在这里试图解决什么问题呢?
Let’s say we have a book store application we want to test with Cucumber. First of all, let’s create that application, which will simply be a Java class:
假设我们有一个想用Cucumber来测试的书店应用程序。首先,让我们创建这个应用程序,它将是一个简单的Java类。
public class BookStore {
private List<Book> books = new ArrayList<>();
public void addBook(Book book) {
books.add(book);
}
public List<Book> booksByAuthor(String author) {
return books.stream()
.filter(book -> Objects.equals(author, book.getAuthor()))
.collect(Collectors.toList());
}
public Optional<Book> bookByTitle(String title) {
return books.stream()
.filter(book -> book.getTitle().equals(title))
.findFirst();
}
}
As we can see, it’s possible to add and search for books in the store. Now, let’s create a few Cucumber sentences to interact with the book store:
正如我们所看到的,可以在商店里添加和搜索书籍。现在,让我们创建几个Cucumber句子来与书店互动。
public class BookStoreRunSteps {
private BookStore store;
private List<Book> foundBooks;
private Book foundBook;
@Before
public void setUp() {
store = new BookStore();
foundBooks = new ArrayList<>();
}
@Given("^I have the following books in the store$")
public void haveBooksInTheStore(DataTable table) {
List<List<String>> rows = table.asLists(String.class);
for (List<String> columns: rows) {
store.addBook(new Book(columns.get(0), columns.get(1)));
}
}
@When("^I search for books by author (.+)$")
public void searchForBooksByAuthor(String author) {
foundBooks = store.booksByAuthor(author);
}
@When("^I search for a book titled (.+)$")
public void searchForBookByTitle(String title) {
foundBook = store.bookByTitle(title).orElse(null);
}
@Then("^I find (\\d+) books$")
public void findBooks(int count) {
assertEquals(count, foundBooks.size());
}
@Then("^I find a book$")
public void findABook() {
assertNotNull(foundBook);
}
@Then("^I find no book$")
public void findNoBook() {
assertNull(foundBook);
}
}
With those sentences, we can add books, search for them by author or title, and check whether we find them or not.
通过这些句子,我们可以添加书籍,按作者或标题搜索,并检查是否找到它们。
Now, everything is set for us to create our feature. We’ll search for books by their author, but also by their title:
现在,一切都准备好了,我们可以创建我们的功能。我们将按作者搜索书籍,但也按书名搜索。
Feature: Book Store Without Background
Scenario: Find books by author
Given I have the following books in the store
| The Devil in the White City | Erik Larson |
| The Lion, the Witch and the Wardrobe | C.S. Lewis |
| In the Garden of Beasts | Erik Larson |
When I search for books by author Erik Larson
Then I find 2 books
Scenario: Find books by author, but isn't there
Given I have the following books in the store
| The Devil in the White City | Erik Larson |
| The Lion, the Witch and the Wardrobe | C.S. Lewis |
| In the Garden of Beasts | Erik Larson |
When I search for books by author Marcel Proust
Then I find 0 books
Scenario: Find book by title
Given I have the following books in the store
| The Devil in the White City | Erik Larson |
| The Lion, the Witch and the Wardrobe | C.S. Lewis |
| In the Garden of Beasts | Erik Larson |
When I search for a book titled The Lion, the Witch and the Wardrobe
Then I find a book
Scenario: Find book by title, but isn't there
Given I have the following books in the store
| The Devil in the White City | Erik Larson |
| The Lion, the Witch and the Wardrobe | C.S. Lewis |
| In the Garden of Beasts | Erik Larson |
When I search for a book titled Swann's Way
Then I find no book
This feature works fine, but it tends to be a bit verbose because we initialize the store for each test. Not only does this create a lot of lines, but if we have to update the store, we have to do it for each test. That’s when Cucumber Backgrounds come handy.
这个功能运行良好,但它往往有点冗长,因为我们为每个测试初始化存储。这不仅会产生大量的行,而且如果我们必须更新存储,我们必须为每个测试做这件事。这时,Cucumber背景就派上用场了。
3. Example
3.例子
So, how to create a background creating the store for this feature? To do this, we must use the keyword Background, give it a title as we do for a Scenario, and define the sentences to execute:
那么,如何创建一个背景,为这个功能创建商店?要做到这一点,我们必须使用关键字Background,像对待Scenario那样给它一个标题,并定义要执行的句子:。
Background: The Book Store
Given I have the following books in the store
| The Devil in the White City | Erik Larson |
| The Lion, the Witch and the Wardrobe | C.S. Lewis |
| In the Garden of Beasts | Erik Larson |
When we’ve done this, we can get rid of this sentence in the tests, letting them focus on their specificities:
当我们做到这一点时,我们就可以在测试中摆脱这句话,让他们专注于他们的特殊性。
Scenario: Find books by author
When I search for books by author Erik Larson
Then I find 2 books
Scenario: Find books by author, but isn't there
When I search for books by author Marcel Proust
Then I find 0 books
Scenario: Find book by title
When I search for a book titled The Lion, the Witch and the Wardrobe
Then I find a book
Scenario: Find book by title, but isn't there
When I search for a book titled Swann's Way
Then I find no book
As we can see, the scenarios are much shorter than before and the remaining sentences focus on what we’re trying to test rather than setting up the data.
我们可以看到,方案比以前短多了,剩下的句子集中在我们要测试的内容上,而不是设置数据。
4. Difference with @Before
4.与@Before的区别
Now, let’s discuss the difference between a Cucumber Background and the @Before hook. The hook also allows us to execute code before a scenario, but this code is hidden from those who are only reading the feature files. On the other hand, a Background is made of sentences that are visible in the feature files.
现在,我们来讨论一下Cucumber背景和@Before钩子之间的区别。钩子也允许我们在一个场景之前执行代码,但这些代码对那些只阅读特征文件的人来说是隐藏的。另一方面,一个背景是由特征文件中可见的句子组成的。
5. Conclusion
5.总结
In this short article, we learned how to use the Cucumber Background feature. It allows us to execute some sentences before each scenario of a feature. We also discussed the difference between this feature and the @Before hook.
在这篇短文中,我们学习了如何使用Cucumber的背景功能。它允许我们在一个功能的每个场景之前执行一些句子。我们还讨论了这个功能和@Before钩子之间的区别。
As usual, the code for this article can be found over on GitHub.
像往常一样,这篇文章的代码可以在GitHub上找到over。