Skip to main content

CORE SYNTAX

Tags

Tags provide powerful mechanisms for organizing tests, controlling execution flow, and managing test visibility in reports. Use tags to create flexible test suites that adapt to different execution contexts.

Basic Tag Usage

Apply tags at feature or scenario level to categorize and filter tests:

@smoke @regression
Feature: User Authentication

@critical @auth
Scenario: Successful login
* print 'Critical authentication test'

@negative @auth
Scenario: Invalid credentials
* print 'Negative test case'

Tag Inheritance

Tags cascade from feature to scenario level:

@api @v2
Feature: API Version 2 Tests

# Inherits @api and @v2 tags
Scenario: Default scenario
* print 'Has tags: @api @v2'

@beta
# Has tags: @api @v2 @beta
Scenario: Beta feature test
* print 'Testing beta feature'

Special Tags

Karate provides special tags with built-in functionality:

@ignore - Skip Execution

@ignore
Scenario: Work in progress
* print 'This scenario will not run'

@ignore @wip
Feature: Future functionality
# Entire feature is skipped

@parallel=false - Sequential Execution

Force sequential execution for specific scenarios:

@parallel=false
Scenario: Database setup
* print 'Must run sequentially'
* call read('setup-database.feature')

@parallel=false
Scenario: Shared resource test
* print 'Accesses exclusive resource'

@report=false - Hide from Reports

Suppress scenarios from HTML reports while still executing them:

@report=false
@ignore
Feature: Utility Functions

Scenario: Reusable authentication
* url authUrl
* path '/login'
* request { username: '#(username)', password: '#(password)' }
* method post
* status 200
* def token = response.token

Use cases for @report=false:

  • Utility features with reusable code
  • Setup/teardown scenarios
  • Internal helper functions
  • Reducing report clutter

Example of a utilities feature:

@ignore @report=false
Feature: Test Utilities

Scenario: Generate test user
* def timestamp = new Date().getTime()
* def user = {
username: 'user_' + timestamp,
email: 'user_' + timestamp + '@example.com',
password: 'Pass123!'
}

Scenario: Clean test data
* call read('classpath:db/cleanup.feature')
* print 'Test data cleaned'

@env - Environment Tags

Link scenarios to specific environments:

@env=dev
Scenario: Development only test
* print 'Runs only in dev environment'

@env=staging,prod
Scenario: Staging and production test
* print 'Runs in staging and prod'

@env!=prod
Scenario: Non-production test
* print 'Skipped in production'

Tag Expressions

Combine tags using logical operators for complex filtering:

AND Logic

# Run scenarios with both tags
mvn test -Dkarate.options="--tags @smoke --tags @critical"

# Or using Runner API
Runner.builder()
.tags("@smoke", "@critical")
.parallel(5);

OR Logic

# Run scenarios with either tag
mvn test -Dkarate.options="--tags @smoke,@regression"

# Using Runner API
Runner.builder()
.tags("@smoke,@regression")
.parallel(5);

NOT Logic

# Exclude scenarios with specific tag
mvn test -Dkarate.options="--tags ~@ignore"

# Multiple exclusions
Runner.builder()
.tags("~@ignore", "~@manual", "~@wip")
.parallel(5);

Complex Expressions

# Combine multiple conditions
mvn test -Dkarate.options="--tags @api --tags ~@slow --tags @v2,@v3"

# This runs scenarios that:
# - Have @api tag AND
# - Don't have @slow tag AND
# - Have either @v2 OR @v3 tag

Tag Organization Strategies

Test Levels

@unit
Scenario: Unit level test
* def result = myFunction(input)
* match result == expected

@integration
Scenario: Integration test
* call read('service1.feature')
* call read('service2.feature')

@e2e
Scenario: End-to-end test
* call read('full-workflow.feature')

Test Categories

@smoke       # Quick validation tests
@regression # Full regression suite
@nightly # Nightly build tests
@performance # Performance tests
@security # Security tests

Feature Areas

@auth        # Authentication features
@payment # Payment processing
@user # User management
@reporting # Reporting features

Priority Levels

@critical    # Must pass for deployment
@high # Important functionality
@medium # Standard features
@low # Nice-to-have features

Dynamic Tag Selection

Using karate.tags

Access and manipulate tags at runtime:

Feature: Dynamic tag handling

Scenario: Check current tags
* def currentTags = karate.tags
* print 'Running with tags:', currentTags
* if (currentTags.contains('@prod')) karate.fail('Should not run in prod!')

Conditional Execution

Feature: Conditional tests

Scenario: Environment-aware test
* def env = karate.env
* def tags = karate.tags

# Skip if not in correct environment
* if (tags.contains('@prod') && env != 'prod') karate.abort()

# Production-specific validations
* match response.secure == true

Tag-based Configuration

// In karate-config.js
function fn() {
var tags = karate.tags;
var config = {};

// Different config based on tags
if (tags.contains('@performance')) {
config.timeout = 60000;
config.retry = 0;
} else if (tags.contains('@smoke')) {
config.timeout = 5000;
config.retry = 3;
} else {
config.timeout = 30000;
config.retry = 1;
}

return config;
}

Tag Reporting

Tag Statistics

Tags appear in test reports with execution statistics:

@metrics @report
Scenario: Track tag metrics
* def startTime = new Date().getTime()
* call read('test-api.feature')
* def duration = new Date().getTime() - startTime
* print 'Test duration:', duration, 'ms'

Custom Tag Reports

Generate tag-based reports:

Results results = Runner.path("classpath:tests")
.tags("@smoke")
.parallel(5);

// Generate tag report
List<String> tagReport = results.getTagResults()
.stream()
.map(tag -> tag.getName() + ": " +
tag.getPassCount() + "/" +
tag.getScenarioCount())
.collect(Collectors.toList());

Best Practices

Tag Naming Conventions

  • Use lowercase with hyphens: @api-v2
  • Prefix categories: @env-staging, @priority-high
  • Keep tags short and descriptive
  • Avoid special characters except hyphen and underscore

Tag Documentation

Document your tag strategy:

# tags.md
## Tag Reference

### Execution Levels
- @smoke - Quick smoke tests (< 5 min)
- @regression - Full regression (< 30 min)
- @extended - Extended tests (> 30 min)

### Environments
- @env=dev - Development only
- @env=staging - Staging only
- @env=prod - Production only

### Special Tags
- @manual - Manual tests (skipped in automation)
- @wip - Work in progress
- @flaky - Known flaky tests

Tag Maintenance

# Validate tag usage
Feature: Tag validation

Scenario: Ensure valid tags
* def validTags = ['@smoke', '@regression', '@api', '@ui']
* def currentTags = karate.tags
* def invalidTags = []

* def validateTags =
"""
function(tags) {
tags.forEach(function(tag) {
if (!validTags.contains(tag)) {
invalidTags.add(tag);
}
});
}
"""
* call validateTags(currentTags)
* match invalidTags == []

Troubleshooting

Tags Not Working

# Debug tag filtering
Scenario: Debug tags
* print 'Feature tags:', karate.feature.tags
* print 'Scenario tags:', karate.scenario.tags
* print 'Effective tags:', karate.tags

Tag Conflicts

# Handle conflicting tags
@api @ui # Conflict - test can't be both
Scenario: Conflicting tags
* def tags = karate.tags
* assert !(tags.contains('@api') && tags.contains('@ui'))

Next Steps