Gherkin(小黄瓜) 参考文档

2019-08-01  本文已影响0人  Graddy

Gherkin使用一组特殊的关键字来为可执行规范赋予结构和意义。每个关键词都被翻译成多种语言;在这篇参考文献中,我们将使用英语。
Gherkin文档中的大多数行都以某个关键字作为开头。
注释行在文件的任何地方都是允许的。它们以零或多个空格开始,然后是一个散列符号(#)和一些文本。注释必须从新的一行开始。
可以使用空格或制表符进行缩进。推荐的缩进级别是两个空格。举个例子:

Feature: Guess the word

  # The first example has two steps
  Scenario: Maker starts a game
    When the Maker starts a game
    Then the Maker waits for a Breaker to join

  # The second example has three steps
  Scenario: Breaker joins a game
    Given the Maker has started a game with the word "silky"
    When the Breaker joins the Maker's game
    Then the Breaker must guess a word with 5 characters

每个步骤的末尾部分(在关键字之后)匹配到一个代码块,称为步骤定义。

关键字

不是空行的每一行都必须以Gherkin关键字开头,然后是您喜欢的任何文本。唯一的例外是特性和场景描述。
主要关键词有:

也有一些次要的关键字:

本地化

小黄瓜被许多语言本地化;每一个都有自己的本地对应的这些关键字。

Feature

Feature关键字的目的是提供软件特性的高级描述,并对相关场景进行分组。
Gherkin文档中的第一个关键字必须始终是Feature,然后是:和描述该特性的简短文本。
您可以在Feature下面添加自由格式的文本来添加更多的描述。
这些描述行在运行时被Cucumber忽略,但是可以用于报告(它们默认包含在html报告中)。

Feature: Guess the word

  The word guess game is a turn-based game for two players.
  The Maker makes a word for the Breaker to guess. The game
  is over when the Breaker guesses the Maker's word.

  Example: Maker starts a game

名称和可选描述对Cucumber没有特殊意义。它们的目的是为您提供一个地方来记录Feature的重要方面,例如一个简短的说明和一组业务规则(一般接受标准)。

当您使用关键字RuleExampleScenario Outline(或它们的别名)开始一行时,Feature的自由格式描述文本将结束。
您可以将标记置于Feature之上,以独立于文件和目录结构对相关特性进行分组。

Descriptions

自由形式的描述(如上所述的Feature)也可以放在Example/ScenarioBackgroundBackground, Scenario OutlineRule下面。
你可以写任何你喜欢的东西,只要没有以关键字开头的行。

Rule

在Gherkin v6中添加了(可选的)Rule关键字。(注意,Gherkin 6还没有包含到Cucumber的所有实现中!)Rule 关键字的目的是表示应该实现的一个业务规则。它为特性提供了附加信息。Rule用于将属于此业务规则的多个场景组合在一起。Rule应该包含一个或多个描述特定规则的场景。Rule不能包含Background
例如:

# -- FILE: features/gherkin.rule_example.feature
Feature: Highlander

  Rule: There can be only One

    Example: Only One -- More than one alive
      Given there are 3 ninjas
      And there are more than one ninja alive
      When 2 ninjas meet, they will fight
      Then one ninja dies (but not me)
      And there is one ninja less alive

    Example: Only One -- One alive
      Given there is only 1 ninja alive
      Then he (or she) will live forever ;-)

  Rule: There can be Two (in some cases)

    Example: Two -- Dead and Reborn as Phoenix
      ...

Example

这是一个说明业务规则的具体示例。它由一系列步骤组成。
关键字Scenario是关键字 Example 的同义词。

您可以有任意多的步骤,但是我们建议您将每个示例的步骤数量保持在3-5个。如果它们变得更长,就会失去作为规范和文档的表达能力。

除了作为规范和文档之外,示例也是一个测试。总的来说,您的示例是系统的可执行规范。

Examples 遵循相同的模式:

Steps

每个step都以关键字 Given, When, Then, AndBut 开头。

Cucumber按您编写的顺序执行场景中的每个步骤,每次执行一个。当Cucumber尝试执行一个步骤时,它会寻找一个匹配的步骤定义来执行。

在寻找步骤定义时,没有考虑关键字。这意味着您不能使用与另一个步骤相同的文本执行Given, When, Then, AndBut步骤。

Cucumber认为以下步骤重复:

Given there is money in my account
Then there is money in my account

这似乎是一个限制,但它迫使你想出一个不那么模糊,更清晰的领域语言:

Given my account has a balance of £430
Then my account should have a balance of £430

Given

Given 步骤用于描述系统的初始上下文—场景。这通常发生在过去。

当Cucumber执行 Given步骤时,它将把系统配置为处于定义良好的状态,例如创建和配置对象或者向测试数据库添加数据

Given 步骤的目的是在用户(或外部系统)开始与系统交互之前(在 When 步骤中)将系统置于已知状态。避免讨论用户在Given步骤中交互。如果您正在创建用例,Given 将是您的先决条件。

有几个Given 步骤是可以的(对于2个及以上的步骤,只需使用AndBut使其更具可读性)。

举几个Given的例子:

When

When 步骤用于描述事件或动作。这可以是与系统交互的人,也可以是由另一个系统触发的事件

强烈建议每个场景只有一个When步骤。如果你觉得有必要添加更多,这通常是一个信号,表明你应该将场景分成多个场景。

例子:

Then

Then 步骤用于描述预期的结果

Then 步骤应该使用一个断言来比较实际的结果(系统实际做了什么)和预期的结果(这个步骤说明了系统应该做什么)

观察应该在可观测的输出上。也就是说,系统输出的东西(报告、用户界面、消息),而不是深藏其中的东西(如数据库)。

例子:

虽然很容易实现只需查看数据库的Then 步骤—但是要抵制这种诱惑!

您应该只验证对用户(或外部系统)可见的结果,而数据库通常不可见。

And, But

如果你有几个Given’s, When’s, 或 Thens,你可以这样写:

Example: Multiple Givens
  Given one thing
  Given another thing
  Given yet another thing
  When I open my eyes
  Then I should see something
  Then I shouldn't see something else

或者,你可以让它阅读更流畅:

Example: Multiple Givens
  Given one thing
  And another thing
  And yet another thing
  When I open my eyes
  Then I should see something
  But I shouldn't see something else

Background

有时候,您会发现自己在某个特性的所有场景中重复相同的Given步骤。

由于它在每个场景中都是重复的,这表明这些步骤对于描述场景并不重要;这些都是偶然的细节。您可以通过将这些Given步骤分组到一个背景部分中,将它们移动到Background中。

Background允许您向特性中的场景添加一些上下文。它可以包含一个或多个Given步骤。

Background在每个场景之前运行,并在任何Before hooks之后运行。在feature 文件中,将Background放在第一个Scenario之前。

每个特性只能有一组Background步骤。如果您需要针对不同的场景使用不同的Background步骤,则需要将它们拆分为不同的功能文件。
例如:

Feature: Multiple site support
  Only blog owners can post to a blog, except administrators,
  who can post to all blogs.

  Background:
    Given a global administrator named "Greg"
    And a blog named "Greg's anti-tax rants"
    And a customer named "Dr. Bill"
    And a blog named "Expensive Therapy" owned by "Dr. Bill"

  Scenario: Dr. Bill posts to his own blog
    Given I am logged in as Dr. Bill
    When I try to post to "Expensive Therapy"
    Then I should see "Your article was published."

  Scenario: Dr. Bill tries to post to somebody else's blog, and fails
    Given I am logged in as Dr. Bill
    When I try to post to "Greg's anti-tax rants"
    Then I should see "Hey! That's not your blog!"

  Scenario: Greg posts to a client's blog
    Given I am logged in as Greg
    When I try to post to "Expensive Therapy"
    Then I should see "Your article was published."
Tips for using Background

例如,如果用户名和站点名对客户机不重要,请使用更高级别的步骤,比如Given I am logged in as a site owner

客户在阅读场景时需要记住这些内容。如果Background超过4行,考虑将一些不相关的细节移动到更高级别的步骤。

使用色彩鲜艳的名字,试着讲述一个故事。人类的大脑跟踪故事比像“用户A”、“用户B”、“网站1”之类的名字。

如果Background部分已经从屏幕上滚动,读者就不再对发生的事情有一个完整的概述了。考虑使用高级步骤,或者拆分*.feature文件

Scenario Outline

Scenario Outline关键字可用于多次运行相同的Scenario,不同的值组合。关键字Scenario Template是关键字Scenario Outline的同义词。

复制和粘贴场景来使用不同的值会很快变得单调和重复:

Scenario: eat 5 out of 12
  Given there are 12 cucumbers
  When I eat 5 cucumbers
  Then I should have 7 cucumbers

Scenario: eat 5 out of 20
  Given there are 20 cucumbers
  When I eat 5 cucumbers
  Then I should have 15 cucumbers

我们可以将这两个类似的场景分解为一个Scenario Outline

场景大纲允许我们通过使用带有< >-分隔符参数的模板更简洁地表达这些场景:

Scenario Outline: eating
  Given there are <start> cucumbers
  When I eat <eat> cucumbers
  Then I should have <left> cucumbers

  Examples:
    | start | eat | left |
    |    12 |   5 |    7 |
    |    20 |   5 |   15 |

Scenario Outline 必须包含Examples(或Scenarios)部分。它的步骤被解释为一个从不直接运行的模板。相反,在它下面的Examples部分中,Scenario Outline对每一行运行一次(不包括第一个标题行)。

这些步骤可以使用<>分隔参数引用样例表中的头。Cucumber将使用表中的值替换这些参数,然后根据步骤定义匹配步骤。

Step Arguments(步骤参数)

在某些情况下,您可能希望将更多的数据传递给一个步骤,而不是一行。为此,Gherkin具有Doc StringsData Tables

Doc Strings

Doc Strings便于将较大的文本传递给步骤定义。

文本应该被分隔符所抵消,由他们自己的两条引号组成:

Given a blog post named "Random" with Markdown body
  """
  Some Title, Eh?
  ===============
  Here is the first paragraph of my blog post. Lorem ipsum dolor sit amet,
  consectetur adipiscing elit.
  """

在您的步骤定义中,不需要找到此文本并将其匹配到您的模式中。它将自动传递作为步骤定义的最后一个参数。

开孔的缩进"""并不重要,虽然通常的做法是在两个空间内从封闭的步骤。然而,三引号内的缩进非常重要。Doc String的每一行都将按照开头的"""缩进。因此,开孔"""栏外的压痕将被保留。

Data Tables

Data Tables可以方便地将值列表传递到步骤定义:

Given the following users exist:
  | name   | email              | twitter         |
  | Aslak  | aslak@cucumber.io  | @aslak_hellesoy |
  | Julien | julien@cucumber.io | @jbpros         |
  | Matt   | matt@cucumber.io   | @mattwynne      |

就像Doc字符串一样,数据表将作为最后一个参数传递给步骤定义。

Spoken Languages (语言/口语)

你选择Gherkin的语言应该是你的用户和领域专家在谈论域时使用的语言。应该避免两种语言之间的翻译。

这就是为什么Gherkin被翻译成超过70种语言的原因。

下面是一个由挪威语编写的Gherkin场景:

# language: no
Funksjonalitet: Gjett et ord

  Eksempel: Ordmaker starter et spill
    Når Ordmaker starter et spill
    Så må Ordmaker vente på at Gjetter blir med

  Eksempel: Gjetter blir med
    Gitt at Ordmaker har startet et spill med ordet "bløtt"
    Når Gjetter blir med på Ordmakers spill
    Så må Gjetter gjette et ord på 5 bokstaver

特性文件第一行的# language: header告诉Cucumber使用什么口语—例如# language: fr表示法语。如果省略此标题,Cucumber将默认为English (en)。
一些Cucumber实现还允许在配置中设置默认语言,因此不需要在每个文件中都放置# language头。

Gherkin Dialects(小黄瓜方言)

为了让小黄瓜可以用多种语言写,关键字已经被翻译成多种语言。为了提高可读性和流,一些语言可能对任何给定的关键字有多个翻译。

List translation options(翻译选项列表)

您可以从命令行获取有关翻译的信息。

查看可用语言的列表:

cucumber --i18n help

要列出特定语言的关键字,请使用语言代码:

cucumber --i18n <language_code>

例如,查看法语中的关键词:

cucumber --i18n fr
链接

https://cucumber.io/docs/gherkin/reference/

上一篇下一篇

猜你喜欢

热点阅读