Cucumber和Background

2023/05/09

1. 概述

在这个简短的教程中,我们将介绍Cucumber中的Background,这是一个允许我们为Cucumber Feature的每次测试执行一些语句的功能。

2. Cucumber Background

首先,让我们解释一下Cucumber Background是什么。它的目的是在每次运行Feature之前执行一个或多个语句。

但是Background在这里试图解决的问题是什么呢?

假设我们有一个想要使用Cucumber进行测试的书店应用程序。首先,让我们创建该应用程序,它只是一个Java类:

public class BookStore {
    private final List<Book> books = new ArrayList<>();

    public void addBook(Book book) {
        books.add(book);
    }

    public void addAllBooks(Collection<Book> books) {
        this.books.addAll(books);
    }

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

如我们所见,可以在BookStore中添加和搜索Book对象。现在,让我们创建一些Cucumber语句来与BookStore交互:

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

通过这些语句定义,我们可以添加Book对象,按作者姓名或书名搜索Book,并检查Book是否存在。

接下来可以创建我们的Feature文件。我们可以按作者名搜索书籍,也可以按书名搜索书籍:

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

这个Feature测试可以正常运行,但它似乎有点冗长,因为我们为每个测试初始化测试数据。这不仅会重复很多行,而且如果我们想要更新测试数据,则必须为每个测试执行此操作。这就是Cucumber Background的用武之地。

3. 例子

那么,如何为这个Feature通过Background创建测试数据呢?为此,我们必须使用关键字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 |

完成此操作后,我们可以去掉之前Feature文件中每个测试的Given子句,让测试的定义专注于自己的功能,而不包含任何数据定义:

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

正如我们所看到的,现在的Feature文件比以前简单地多。

4. 与@Before的区别

现在,让我们讨论Cucumber Background和@Before钩子之间的区别。钩子还允许我们在场景之前执行代码,但是这些代码对那些只阅读Feature文件的人是隐藏的。另一方面,Background由Feature文件中可见的语句组成。

5. 总结

在这篇简短的文章中,我们学习了如何使用Cucumber的Background功能。它允许我们在功能的每个场景之前执行一些语句。我们还讨论了此功能与@Before钩子之间的区别。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章