#code coverage

Line coverage for the code your specs exercise. No extra modules, no plugins. Pass --coverage, point at your lib/, and Behave records which lines ran during the test suite.

behave --coverage --coverage-dir lib specs/
⮑ 'Account' ⮑ 'starts with the configured balance' ⮑ SUCCESS ⮑ 'increases the balance on deposit' ⮑ SUCCESS 2 examples, 0 failed, 2 passed Coverage:
coverage report
  lib/Account.rakumod         100%   42 / 42
  lib/ShoppingCart.rakumod    96%    48 / 50    miss: 33, 41
  lib/Invoice.rakumod         78%    61 / 78    miss: 22-29, 51-58, 66
  lib/Receipt.rakumod         12%    3 / 25    miss: 4-9, 12-25

  Total                       82%   154 / 195
CI-ready. Pair --coverage with --format json and the report ships with structured coverage data your pipeline can gate on.

#doc extraction

Your specs already describe what the code does in English. Behave's doc extractor turns them into Markdown. Descriptions become headings, examples become prose, nested groups become nested sections. The cheapest documentation you'll ever ship is the documentation you already wrote.

behave --format documentation specs/ > docs/behavior.md
# Calculator

## addition

- adds positive numbers
- overflows on MAX_INT
- handles negative-zero (pending: not yet implemented)

## subtraction

- subtracts a positive from a positive
- subtracts a negative from a positive

# Account

- starts with the configured balance

## after a deposit

- increases the balance
- records the transaction
- emits a deposit event

The richer DocExtractor module lets you script your own pipeline: pull the spec tree, walk it, render to any target format your team uses.

#timing & slow-test detection

Every example is timed. Pass --profile for a "top N slowest" report, or --slow-threshold N to flag any example over N seconds inline as it runs. No instrumentation, no separate tooling.

behave --profile --slow-threshold 0.1 specs/
⮑ 'integration' ⮑ 'talks to the database' ⮑ SUCCESS (SLOW: 0.43s) ⮑ 'renders the report' ⮑ SUCCESS 12 examples, 0 failed, 12 passed Top 5 slowest examples: 0.43s integration talks to the database specs/db-spec.raku:8 0.27s reports renders the report specs/report-spec.raku:14 0.11s auth signs and verifies a JWT specs/auth-spec.raku:22 0.04s cache evicts the oldest entry specs/cache-spec.raku:31 0.03s parser handles deeply nested expressions specs/parser-spec.raku:67

#memory profiling

--memory-profile records per-example RSS delta and prints a "top N memory-heaviest" report. --memory-threshold KB flags any example whose memory growth exceeds the threshold inline. Useful for catching leaks in long-running fixtures.

behave --memory-profile --memory-threshold 2048 specs/
⮑ 'image processing' ⮑ 'resizes a 4k jpeg' ⮑ SUCCESS (MEMORY: +5.8 MB) ⮑ 'thumbnails a batch' ⮑ SUCCESS Top 3 memory-heaviest examples: +5.8 MB image processing resizes a 4k jpeg specs/img-spec.raku:8 +0.9 MB reports builds the PDF specs/report-spec.raku:32 +0.3 MB parser parses 10k lines specs/parser-spec.raku:54

#benchmarks & regression detection

Behave includes a benchmark harness with statistical summaries (mean, median, stddev, iterations) and an optional baseline file so you can detect regressions across runs. Mark a block as a benchmark. Behave records, summarizes, and (if enabled) compares.

use BDD::Behave;
use BDD::Behave::Benchmark;

describe 'serialization', {
  benchmark 'json encode a 10k-row payload', {
    JSON::Fast::to-json(@payload);
  }

  benchmark 'msgpack encode a 10k-row payload', {
    MsgPack::encode(@payload);
  }
}
behave --benchmark --benchmark-baseline bench.json specs/
Benchmarks: json encode a 10k-row payload mean: 4.21ms median: 4.18ms stddev: 0.11ms iter: 200 vs baseline: +2.4% faster msgpack encode a 10k-row payload mean: 1.83ms median: 1.80ms stddev: 0.06ms iter: 200 vs baseline: -11.7% regression ⚠ Regressions detected (threshold 5%): 1
Bisect support. The BDD::Behave::Bisect module narrows down which example introduces a failure when running a test ordering. Think git bisect, but for spec order dependencies.

#diff output

When an eq or be matcher fails on a structural value, Behave renders a colorized inline diff alongside the standard Expected: / to be: block. No more eyeballing two twenty-line hashes side by side.

behave specs/user-spec.raku
⮑ 'User#to-hash' ⮑ 'serializes the user' ⮑ FAILURE Failures: [ ✗ ] specs/user-spec.raku:18 Expected: { name => "Ada", role => "admin", age => 31 } to be: { name => "Ada", role => "user", age => 30 } Diff: { name => "Ada", - role => "admin", + role => "user", - age => 31, + age => 30, } 1 example, 1 failed, 0 passed