1. 概要

この短いチュートリアルでは、 Cucumber Backgroundsについて学習します。これは、Cucumber機能のテストごとにいくつかの文を実行できる機能です。

2. きゅうりの背景

まず、きゅうりの背景とは何かを説明しましょう。 その目的は、機能の各テストの前に1つ以上の文を実行することです。

しかし、ここでどのような問題を解決しようとしていますか?

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

ご覧のとおり、ストアで本を追加して検索することができます。 それでは、書店とやり取りするためのキュウリの文章をいくつか作成しましょう。

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

これらの文章を使用して、本を追加したり、著者やタイトルで検索したり、見つけたかどうかを確認したりできます。

これで、機能を作成するためのすべての準備が整いました。 著者だけでなく、タイトルでも本を検索します。

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

この機能は正常に機能しますが、各テストのストアを初期化するため、少し冗長になる傾向があります。 これにより多くの行が作成されるだけでなく、ストアを更新する必要がある場合は、テストごとに更新する必要があります。 キュウリの背景が重宝するのはその時です。

3. 例

では、この機能のストアを作成する背景を作成するにはどうすればよいですか? これを行うには、キーワードBackgroundを使用し、シナリオの場合と同じようにタイトルを付け、実行する文を定義する必要があります。

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 |

これを行うと、テストでこの文を取り除き、特定性に焦点を当てることができます。

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

ご覧のとおり、シナリオは以前よりもはるかに短く、残りの文はデータを設定するのではなく、テストしようとしていることに焦点を当てています。

4. @Beforeとの違い

それでは、キュウリの背景と@Beforeフックの違いについて説明しましょう。 フックを使用すると、シナリオの前にコードを実行することもできますが、このコードは、機能ファイルのみを読み取っているユーザーには表示されません。 一方、背景は、機能ファイルに表示される文で構成されています。

5. 結論

この短い記事では、キュウリの背景機能の使用方法を学びました。 これにより、機能の各シナリオの前にいくつかの文を実行できます。 この機能と@Beforeフックの違いについても説明しました。

いつものように、この記事のコードはGitHubにあります。