Parallel Execution
BehaveX manages concurrent Behave instances across multiple processes. You can run tests in parallel by feature or by scenario. When using the scenario scheme, examples within a scenario outline are also parallelized.

Basic Usage
behavex --parallel-processes=3
behavex -t=@TAG --parallel-processes=3
behavex -t=@TAG --parallel-processes=2 --parallel-scheme=scenario
behavex -t=@TAG --parallel-processes=5 --parallel-scheme=feature
behavex -t=@TAG --parallel-processes=5 --parallel-scheme=feature --show-progress-bar
Worker ID
BehaveX injects the worker_id variable into each Behave process context. With --parallel-processes 2, the first instance receives worker_id=0 and the second receives worker_id=1.
Access it in step definitions or hooks:
context.config.userdata['worker_id']
Hooks in Parallel Execution
Hook Firing Matrix
Hook |
Sequential |
|
|
|---|---|---|---|
|
Once — coordinator |
Once — coordinator |
Once — coordinator |
|
Once |
Once per worker |
Once per worker |
|
Once per feature |
Once per feature ✓ |
Once per scenario ⚠ |
|
Once per scenario |
Once per scenario |
Once per scenario |
|
Once per scenario |
Once per scenario |
Once per scenario |
|
Once per feature |
Once per feature ✓ |
Once per scenario ⚠ |
|
Once |
Once per worker |
Once per worker |
|
Once — coordinator |
Once — coordinator |
Once — coordinator |
⚠ scenario scheme: Each worker process runs a single scenario. As a result,
before_featureandafter_featurefire once per scenario — the same frequency asbefore_scenario/after_scenario.
BehaveX-Specific Hooks
BehaveX adds before_all_workers and after_all_workers, which run once in the coordinator process — before any worker starts and after all workers finish. They are the right place for global setup/teardown that must not repeat across workers.
def before_all_workers(context):
# Values set here are injected into every worker's context before before_all fires.
context.base_url = "https://staging.example.com"
context.db_name = "test_db"
context.retry_count = 3
def after_all_workers(context):
print(f"All workers finished. Base URL was: {context.base_url}")
Important: Values set on
contextinbefore_all_workersmust be JSON-serializable (str, int, float, bool, list, dict, or None). Non-serializable values (e.g., database connections, sockets) raise aTypeErrorimmediately.
Execution Metadata: context.behavex
BehaveX injects a context.behavex namespace in every worker process, available from before_all onwards:
Attribute |
Type |
Description |
|---|---|---|
|
|
|
|
|
Number of parallel workers configured |
|
|
|
|
|
Worker index (0 in single-process mode) |
Guard feature-level setup in scenario-parallel mode:
def before_feature(context, feature):
if context.behavex.parallel_scheme == 'scenario':
return # fires once per scenario here — move setup to before_scenario
setup_feature_database(feature.name)
def after_feature(context, feature):
if context.behavex.parallel_scheme == 'scenario':
return
teardown_feature_database(feature.name)
Allocate resources per worker:
def before_all(context):
if context.behavex.is_worker:
context.browser = create_browser(worker_id=context.behavex.worker_id)
def after_all(context):
if context.behavex.is_worker:
context.browser.quit()
Test Execution Ordering
BehaveX lets you control the execution order of scenarios and features in parallel runs using special order tags.
Use Cases
Setup/teardown: Ensure setup scenarios run first and cleanup runs last
Data dependencies: Run data-creation tests before tests that consume that data
Smoke testing: Prioritize critical smoke tests
Parallel optimization: Run slower scenarios first to maximize worker utilization
Regular vs Strict Ordering
Regular Ordering (--order-tests)
Tests are sorted by order tags but can run simultaneously if parallel processes are available.
behavex --order-tests --parallel-processes=4 -t=@SMOKE
Faster: all processes run concurrently
Best for: performance optimization, general prioritization
Strict Ordering (--order-tests-strict)
Tests wait for all lower-order tests to complete before starting.
behavex --order-tests-strict --parallel-processes=3 -t=@INTEGRATION
Slower but guaranteed:
@ORDER_002won’t start until all@ORDER_001tests finishBest for: setup/teardown sequences, strict data dependencies
--order-tests-strictautomatically enables--order-tests
Performance comparison:
Scenario: 6 tests tagged ORDER_001, ORDER_002, ORDER_003 with 3 parallel processes
Regular ordering (--order-tests):
Time 0: ORDER_001, ORDER_002, ORDER_003 all start simultaneously
Total time: ~1 minute
Strict ordering (--order-tests-strict):
Time 0: Only ORDER_001 tests start
Time 1: ORDER_001 finishes → ORDER_002 starts
Time 2: ORDER_002 finishes → ORDER_003 starts
Total time: ~3 minutes
Custom Order Prefix
behavex --order-tests --order-tag-prefix=PRIORITY --parallel-processes=3
@PRIORITY_001
Scenario: High priority scenario
@PRIORITY_050
Scenario: Medium priority scenario
@PRIORITY_100
Scenario: Low priority scenario
Feature-Level Ordering
When using --parallel-scheme=feature, place order tags on the feature itself:
@ORDER_001
Feature: Database Setup
Scenario: Create schema
Scenario: Insert initial data
@ORDER_002
Feature: Application Tests
Scenario: Test user login
Feature: Unordered Feature
# No ORDER tag — gets default order 9999