Skip to main content

Tags

Organize tests and control execution using Gherkin tags. Tags provide powerful meta-data for partitioning tests into categories like smoke, regression, and environment-specific subsets.

Basic Tag Usage

Add tags above scenarios to categorize and filter tests:

@userApi @positive
Feature: User API

@smoke @fast
Scenario: Quick user lookup
Given path 'users/1'
When method get
Then status 200

@regression @auth
Scenario: User authentication flow
Given path 'auth/login'
And request { username: 'test', password: 'secret' }
When method post
Then status 200

@integration @slow
Scenario: Cross-system user sync
Given path 'sync/users'
When method post
Then status 202

Running Tests with Tags

Command Line Filtering

Command Line
# Run only smoke tests
mvn test -Dkarate.options="--tags @smoke"

# Exclude slow tests
mvn test -Dkarate.options="--tags ~@slow"

# Run tests with either tag (OR)
mvn test -Dkarate.options="--tags @api,@integration"

# Run tests with both tags (AND)
mvn test -Dkarate.options="--tags @smoke and @auth"

Parallel Runner with Tags

@Test
void smokeTests() {
Results results = Runner.path("classpath:features")
.tags("@smoke")
.parallel(5);
assertEquals(0, results.getFailCount());
}

@Test
void regressionExcludingSlow() {
Results results = Runner.path("classpath:features")
.tags("@regression", "~@slow") // AND operation
.parallel(8);
assertEquals(0, results.getFailCount());
}

Special Built-In Tags

@ignore Tag

Skip scenarios without deleting them:

Feature: Work in progress

@ignore
Scenario: Not ready yet * print 'This will not execute'

@ignore @reason=bug-fix-pending
Scenario: Known issue * print 'Skip until bug is fixed'

Scenario: Active test * print 'This will execute normally'

The @ignore tag is automatically excluded - no need to specify ~@ignore.

@ignore with Called Features

Scenarios marked with @ignore are skipped during test execution but can still be called using call or callonce. This is useful for creating reusable helper scenarios.

See Calling Features for examples.

@parallel=false Tag

Force sequential execution when test independence isn't possible:

@parallel=false
Feature: Database setup
# All scenarios run sequentially

Scenario: Create tables * call read('create-schema.feature')

Scenario: Insert test data
* call read('insert-data.feature')
Anti-Pattern

Sequential execution indicates test dependencies. Design independent scenarios when possible.

Environment-Specific Tags

@env Tag

Run scenarios only in specific environments:

@env=dev,test
Scenario: Development testing
* print 'Only runs in dev or test environments'

@env=prod
Scenario: Production health check
Given path 'health'
When method get
Then status 200

@envnot Tag

Exclude scenarios from specific environments:

@envnot=prod
Scenario: Destructive test
* print 'Never runs in production'

@envnot=local
Scenario: External service test

* print 'Requires external dependencies'

Tag Strategies

Common Tag Categories

CategoryExamplesPurpose
Contract Testing@positive, @negativeTesting Phases
Execution Phase@smoke, @regression, @integrationCI/CD pipeline stages
Performance@fast, @slow, @loadExecution time management
Business Domain@auth, @payment, @userFeature area organization
Risk Level@critical, @high, @mediumPriority-based testing

Tag Combinations

Feature: Multi-dimensional tagging

@smoke @auth @fast @critical
Scenario: Critical auth smoke test # Runs in smoke, auth, fast, and critical test suites

@regression @payment @slow @integration
Scenario: Payment integration test # Comprehensive payment workflow testing

Advanced Tag

Advanced Tag Features

Tags with Values

Create structured metadata using key-value tags:

@module=auth @priority=high @owner=team-alpha
Scenario: Structured tagging
* def tagValues = karate.tagValues
* def module = tagValues.module[0]
* def priority = tagValues.priority[0]
* print 'Testing module:', module, 'priority:', priority

Call with Tag Selectors

Select specific scenarios when calling features:

Feature: Tag-based calling

Background: * call read('setup.feature@database')

Scenario: Main test
* call read('workflows.feature@name=createUser')
* call read('cleanup.feature@cleanup')

Debugging Tag Issues

To troubleshoot tag-related problems:

  • Use karate.tags to log applied tags: * print karate.tags.
  • Verify tag filtering in karate.log with .systemProperty("log.level", "DEBUG").
  • Run a single feature with specific tags to isolate issues: mvn test -Dkarate.options="classpath:feature.feature --tags @smoke".

Tag-Based Reporting

Filter reports by tags for analysis:

  • Generate tag-specific reports: Runner.path("classpath:features").tags("@smoke").outputCucumberJson(true).
  • Use karate-timeline.html to view tag distribution across threads.
  • In CI, archive tag-based reports: target/karate-reports/smoke.cucumber.json.

CI/CD Integration with Tags

Example for GitHub Actions to run tagged tests:

Tag Best Practices

Clear Naming Conventions

# Good: Consistent, descriptive tags
@smoke @auth @fast
@regression @payment @integration
@critical @security @compliance

# Avoid: Inconsistent naming

@Test1 @SMOKE @Payment @fast_test

Balanced Tag Strategy

  • Keep it simple: 3-5 tag dimensions maximum
  • Be consistent: Establish naming conventions
  • Document strategy: Maintain tag definitions
  • Regular cleanup: Remove unused tags
  • Optimize for performance: Avoid complex tag expressions (e.g., (@smoke or @critical) and not @flaky) for large suites.

Common Gotchas

  • Feature-level tags: Inherited by all scenarios in the feature
  • Tag syntax: Must start with @ and contain no spaces
  • Case sensitivity: Tags are case-sensitive (@Smoke@smoke)
  • Inheritance: Scenario tags combine with feature-level tags
  • Performance: Complex tag filters can slow test selection in large suites

Next Steps

Organize tests effectively with tags: