Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Tags

Tags represent meta information of scenarios and features.

They can be used for different purposes, but in the majority of cases it's just:

  • either running a subset of scenarios filtering by tag;
  • or making scenario run in isolation via @serial tag;
  • or allowing scenarios to be skipped with @allow.skipped tag.

Filtering

A scenario may have as many tags as it requires (they should be separated with spaces):

Feature: Animal feature

  @hungry
  Scenario: If we feed a hungry cat it will no longer be hungry
    Given a hungry cat
    When I feed the cat
    Then the cat is not hungry

  @satiated @second
  Scenario: If we feed a satiated cat it will not become hungry
    Given a satiated cat
    When I feed the cat
    Then the cat is not hungry

To filter out running scenarios we may use:

record

Inheritance

Tags may be placed above the following Gherkin elements:

It's not possible to place tags above Background or steps (Given, When, Then, And and But).

Tags are inherited by child elements:

@feature
Feature: Animal feature

  @scenario
  Scenario Outline: If we feed a hungry animal it will no longer be hungry
    Given a hungry <animal>
    When I feed the <animal> <n> times
    Then the <animal> is not hungry

  @home
  Examples: 
    | animal | n |
    | cat    | 2 |
    | dog    | 3 |

  @dire
  Examples: 
    | animal | n |
    | lion   | 1 |
    | wolf   | 1 |

NOTE: In Scenario Outline it's possible to use tags on different Examples.

record

Isolated execution

cucumber crate provides out-of-the-box support for @serial tag. Any scenario marked with @serial tag will be executed in isolation, ensuring that there are no other scenarios running concurrently at the moment.

Feature: Animal feature
    
  Scenario: If we feed a hungry cat it will no longer be hungry
    Given a hungry cat
    When I feed the cat
    Then the cat is not hungry

  @serial
  Scenario: If we feed a satiated cat it will not become hungry
    Given a satiated cat
    When I feed the cat
    Then the cat is not hungry

NOTE: @serial tag may also be used for filtering as a regular one.

record

TIP: To run the whole test suite serially, consider using --concurrency=1 CLI option, rather than marking evey single feature with a @serial tag.

Failing on skipped steps

As a test suit grows, it may become harder to notice how minimal changes to regular expressions can lead to mismatched steps.

Using Cucumber::fail_on_skipped() method fails the whole test suite if some steps miss the implementation, so ensures that the whole test suite is covered.

Feature: Animal feature
    
  Scenario: If we feed a hungry cat it will no longer be hungry
    Given a hungry cat
    When I feed the cat
    Then the cat is not hungry

  Scenario: If we feed a satiated cat it will not become hungry
    Given a wild cat
    When I feed the cat
    Then the cat is not hungry
extern crate cucumber;
extern crate tokio;

use std::time::Duration;

use cucumber::{World, given, then, when};
use tokio::time::sleep;

#[derive(Debug, Default)]
struct Animal {
    pub hungry: bool,
}

impl Animal {
    fn feed(&mut self) {
        self.hungry = false;
    }
}

#[derive(Debug, Default, World)]
pub struct AnimalWorld {
    cat: Animal,
}

#[given(regex = r"^a (hungry|satiated) cat$")]
async fn hungry_cat(world: &mut AnimalWorld, state: String) {
    sleep(Duration::from_secs(2)).await;

    match state.as_str() {
        "hungry" => world.cat.hungry = true,
        "satiated" => world.cat.hungry = false,
        _ => unreachable!(),
    }
}

#[when("I feed the cat")]
async fn feed_cat(world: &mut AnimalWorld) {
    sleep(Duration::from_secs(2)).await;

    world.cat.feed();
}

#[then("the cat is not hungry")]
async fn cat_is_fed(world: &mut AnimalWorld) {
    sleep(Duration::from_secs(2)).await;

    assert!(!world.cat.hungry);
}

#[tokio::main]
async fn main() {
    AnimalWorld::cucumber()
        .fail_on_skipped()
        .run_and_exit("tests/features/book/writing/tags_skip_failed.feature")
        .await;
}

TIP: Using @allow.skipped tag allows scenarios being skipped even in Cucumber::fail_on_skipped() mode. Use the one to intentionally skip the implementation.

Feature: Animal feature
    
  Scenario: If we feed a hungry cat it will no longer be hungry
    Given a hungry cat
    When I feed the cat
    Then the cat is not hungry

  @allow.skipped
  Scenario: If we feed a satiated cat it will not become hungry
    Given a wild cat
    When I feed the cat
    Then the cat is not hungry

record

NOTE: @allow.skipped tag may also be used for filtering as a regular one.

record