Skip to content

Instantly share code, notes, and snippets.

@richard-wolsch
Created March 22, 2024 13:32
Show Gist options
  • Save richard-wolsch/c22fddaf978a830667db8fcb2e88d27e to your computer and use it in GitHub Desktop.
Save richard-wolsch/c22fddaf978a830667db8fcb2e88d27e to your computer and use it in GitHub Desktop.
Use Cucumber tags in context files

If you want to check out the @tags within a .feature file inside your Cucumber test context, then your context class should just use the following trait:

CucumberTagsTrait

<?php

namespace App\Tests\Context\Tags;

use Behat\Behat\Hook\Scope\BeforeScenarioScope;

/**
 * Provides all the tags given in feature and scenario.
 */
trait CucumberTagsTrait
{

    /** @var string[] */
    private array $tags = [];

    /**
     * @BeforeScenario
     *
     * @param BeforeScenarioScope $scope
     */
    public function loadTagsBeforeTest(BeforeScenarioScope $scope): void
    {
        $this->tags = $scope->getScenario()->getTags();
        $this->tags = array_merge($this->tags, $scope->getFeature()->getTags());
    }

    /**
     * This includes all tags attached to the current scenario and also the whole feature.
     * @return string[]
     */
    private function getTags(): array
    {
        return $this->tags;
    }

    /**
     * Checks if the given tag is associated with the current scenario or feature.
     * @param CucumberTag $tag
     *
     * @return bool <code>true</code> if tag is attached to scenario or feature, <code>false</code> if not.
     */
    private function hasTag(CucumberTag $tag): bool
    {
        return in_array($tag->value, $this->tags, true);
    }

}

CucumberTag

This is an enum with some example tags. Edit it to your needs.

<?php

namespace App\Tests\Context\Tags;

/**
 * Common Cucumber tags.
 */
enum CucumberTag: string
{
    case JustATestTag = 'JustATestTag';
    case JustAnotherTestTag = 'JustAnotherTestTag';
    case UnusedTag = 'UnusedTag';
}

Test Feature

A feature could use the tags like here:

@JustATestTag
Feature: This is my feature description.

  @JustAnotherTestTag
  Scenario: I log into my application
    Given I am on "login/"
    # …

Test Context

This example illustrates the usage:

final class MyContext extends RawMinkContext
{

    use CucumberTagsTrait;

    // …
    
    /**
     * @Given I am on :route
     *
     * @param string $route
     */
    public function iAmOnRoute(string $route): void
    {
        $tags = $this->getTags();
        // ['JustATestTag', 'JustAnotherTestTag']
        
        $hasATestTag = $this->hasTag(CucumberTag::JustATestTag);
        // true
        
        $hasAnotherTestTag = $this->hasTag(CucumberTag::JustAnotherTestTag);
        // true
        
        $hasUnusedTag = $this->hasTag(CucumberTag::UnusedTag);
        // false
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment