1. Overview
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.
2. Cucumber Background
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:
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:
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.
3. Example
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: 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
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.
5. Conclusion
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.
As usual, the code for this article can be found over on GitHub.