behave-pool
August 6, 2026 · View on GitHub
Parallel test execution for Behave BDD via
native ITestRunner. Workers run in isolated processes with spawn start
method for clean interpreter state on every platform.
Features
- Native ITestRunner — Registered via
--runner=orbehave.ini. Zero monkey-patching. - Process isolation —
spawnstart method ensures clean state in every worker, on every OS. - Dynamic dispatch —
multiprocessing.Process+Queue. Workers consume work units as they finish. - @serial tag — Non-parallelizable scenarios run sequentially after the parallel phase.
- LPT load balancing — Historical durations for optimal work distribution.
- Timing persistence —
.behave-pool-timing.jsonstores durations between runs. - Sharding — Split the suite across CI runners with
--shard INDEX/TOTAL. Deterministic, compatible with--paralleland@serial. - Unified JSON report — Merges all worker reports into a single
behave-modern-json-reportExecutionReport (schema v1.1.0) with statistics, environment info, and full feature/scenario/step details. - Ecosystem integration — Optional
behave-priority,behave-modern-json-report. The unified report is directly consumable by any tool in the ecosystem. - Zero heavy dependencies — Only stdlib
multiprocessing+behave>=1.3.0.
Installation
pip install behave-pool
Quick start
-
Register the runner in your
behave.ini:[behave.runners] parallel = behave_pool:ParallelRunner -
Run Behave with parallel workers:
behave --runner=parallel --parallel 4 --parallel-scheme feature features/
How it works
┌─────────────────────────────────────────────────┐
│ ParallelRunner │
│ │
│ 1. Plan — parse features, create work units │
│ 2. Split — separate @serial from parallel │
│ 3. Dispatch — N workers consume from queue │
│ 4. Collect — gather results, update timings │
│ 5. Serial — run @serial units one at a time │
└─────────────────────────────────────────────────┘
│ │
┌────▼────┐ ┌────▼────┐
│ Worker 0 │ │ Worker N │
│ (spawn) │ ... │ (spawn) │
│ │ │ │
│ parse │ │ parse │
│ features │ │ features │
│ run │ │ run │
│ report │ │ report │
└──────────┘ └──────────┘
Each worker runs in an isolated process with the spawn start method,
guaranteeing a clean interpreter state regardless of OS or Python version.
Workers consume work units from a shared JoinableQueue and write
WorkerResult objects back to a result queue. The coordinator collects
results, persists timings, and returns the aggregated exit code.
CLI options
| Option | Default | Description |
|---|---|---|
--parallel N | 1 | Number of worker processes. 1 = sequential passthrough. |
--parallel-scheme | feature | Parallelization unit: feature (scenario planned for future). |
--parallel-balance | lpt | Work ordering: lpt (longest first) or fifo (insertion order). |
--parallel-timing-file | .behave-pool-timing.json | Path to timing file for LPT balancing. |
--parallel-report | behave-pool-report.json | Path to unified JSON report (behave-modern-json-report format). |
--shard INDEX/TOTAL | (disabled) | Run only shard INDEX of TOTAL for CI parallelism across machines. |
Usage
Feature-level parallelization
Each feature file runs in its own worker process. Workers are dispatched dynamically and consume work units from a shared queue.
# 4 worker processes, LPT balancing
behave --runner=parallel --parallel 4 features/
Serial scenarios
Tag scenarios with @serial to run them sequentially after all parallel work units complete:
@serial
Scenario: Database migration
Given the database is empty
When I run the migration
Then all tables should exist
LPT load balancing
By default, behave-pool uses Longest Processing Time (LPT) scheduling. It stores historical durations in .behave-pool-timing.json and dispatches the slowest features first, minimizing total wall-clock time.
# Use FIFO ordering instead of LPT
behave --runner=parallel --parallel 4 --parallel-balance fifo features/
Unified JSON report
After all workers finish, behave-pool merges their results into a single
JSON report in the behave-modern-json-report
ExecutionReport format (schema v1.1.0). This report includes:
- Execution metadata — unique ID, status, duration, timestamps.
- Aggregate statistics — feature/scenario/step counts, pass rate, error count, per-tag breakdown.
- Environment info — Python and Behave versions, OS, CI provider, git branch/commit.
- Full feature tree — features, scenarios, and steps with IDs, locations, durations, errors, and tracebacks.
# Default report path
behave --runner=parallel --parallel 4 features/
# → writes behave-pool-report.json
# Custom report path
behave --runner=parallel --parallel 4 \
--parallel-report reports/run.json \
features/
Any tool built for the behave-modern-json-report ecosystem (HTML formatters,
dashboards, AI analyzers) can consume the parallel report directly — no
conversion needed.
Sharding
Split the test suite across multiple CI runners. Each runner executes only its assigned shard:
# Runner 1 of 3
behave --runner=parallel --parallel 4 --shard 1/3 features/
# Runner 2 of 3
behave --runner=parallel --parallel 4 --shard 2/3 features/
# Runner 3 of 3
behave --runner=parallel --parallel 4 --shard 3/3 features/
Sharding composes with all other features:
--parallel: local parallelism within each shard.@serial: serial scenarios run sequentially within the shard.--tags: tag filtering applies before sharding.
The algorithm sorts work units deterministically by ID, then splits
them into TOTAL contiguous groups. The first len % TOTAL shards
receive one extra work unit.
Output includes shard metadata:
Shard 1/3 — 4 scenarios selected (of 10 total)
Python API:
from behave_pool import ShardConfig, run_with_shard
config = ShardConfig(
shard_index=1,
total_shards=3,
features_dir="features/",
parallel=4,
)
failed = run_with_shard(config)
behave.ini configuration
All CLI options can also be set in behave.ini:
[behave]
parallel = 4
parallel-scheme = feature
parallel-balance = lpt
parallel-timing-file = .behave-pool-timing.json
parallel-report = behave-pool-report.json
shard = 1/3
Requirements
- Python >=3.11
- behave >=1.3.0
Example
A complete working example is included in examples/calculator/.
It demonstrates parallel execution, @serial scenarios, and the unified JSON report:
cd examples/calculator
behave --runner=parallel --parallel 4
# → runs 3 scenarios (2 parallel + 1 @serial)
# → writes behave-pool-report.json with ExecutionReport format
Documentation
Full documentation is available at https://mathiaspaulenko.github.io/behave-pool/.
Contributing
Contributions are welcome! See CONTRIBUTING.md for setup instructions and guidelines.
Please review our Code of Conduct before participating.
Changelog
See CHANGELOG.md for notable changes.
License
MIT — Copyright (c) 2026 Mathias Paulenko
Acknowledgements
- Behave — the BDD framework this library extends.
- Contributor Covenant — Code of Conduct.
- Keep a Changelog — Changelog format.