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
- Learn about Test Configuration for environment-specific execution
- Explore Parallel Execution with tag-based filtering
- Review Assertions for tag-based validation patterns