The spec we'll run

describe 'Calculator', {
  context 'addition', {
    it 'adds positive numbers',  { expect(1 + 1).to.be(2) }
    it 'overflows on MAX_INT',   { expect(2147483647 + 1).to.be(-2147483648) }
    pending 'handles negative-zero', 'not yet implemented', { }
  }

  context 'subtraction', {
    it 'subtracts a positive',   { expect(5 - 3).to.be(2) }
  }
}

The classic indented tree. One line per describe/context/it, with a colored SUCCESS / FAILURE marker per example. Useful for debugging: you can see exactly which example is running when something hangs.

behave --format tree specs/calc-spec.raku
⮑ 'Calculator' ⮑ 'addition' ⮑ 'adds positive numbers' ⮑ SUCCESS ⮑ 'overflows on MAX_INT' ⮑ FAILURE ⮑ 'handles negative-zero' ⮑ PENDING ⮑ 'subtraction' ⮑ 'subtracts a positive' ⮑ SUCCESS Failures: [ ✗ ] specs/calc-spec.raku:5 Expected: 2147483648 to be: -2147483648 4 examples, 1 failed, 1 pending, 2 passed

The default. One character per example: . pass, F fail, * pending, S skipped. Failures and counts print after the stream completes.

behave --format progress specs/calc-spec.raku
.F*. Failures: [ ✗ ] specs/calc-spec.raku:5 Expected: 2147483648 to be: -2147483648 4 examples, 1 failed, 1 pending, 2 passed

A clean, document-style rendering of the spec tree. Each group is a heading, each example a line beneath it. Outcome suffixes ((FAILED), (PENDING)) annotate non-passing examples.

behave --format documentation specs/calc-spec.raku
Calculator addition adds positive numbers overflows on MAX_INT (FAILED) handles negative-zero (PENDING) subtraction subtracts a positive Failures: [ ✗ ] specs/calc-spec.raku:5 Expected: 2147483648 to be: -2147483648 4 examples, 1 failed, 1 pending, 2 passed

A self-contained HTML5 report with collapsible describe/context nesting using native <details>, no JavaScript required. Inline styles, no external CSS. Redirect to a file and open it.

behave --format html specs/ > report.html

4 examples, 1 failed, 1 pending, 2 passed

Calculator
addition
✓ adds positive numbers (0.001s · specs/calc-spec.raku:3)
✗ overflows on MAX_INT (0.001s · specs/calc-spec.raku:5)
specs/calc-spec.raku:5
  Expected: 2147483648
  to be:    -2147483648
⏸ handles negative-zero (pending: not yet implemented)
subtraction
✓ subtracts a positive (0.001s · specs/calc-spec.raku:10)

↑ Rendered preview of the HTML formatter's output. Open the real report.html and you'll see this with click-to-collapse working out of the box.

A single JSON document emitted on stdout after the run finishes. Designed for CI dashboards and tool integration. Stable, versioned schema.

{
  "version": 1,
  "order": "random",
  "seed": 42,
  "aborted": false,
  "examples": [
    {
      "description": "adds positive numbers",
      "full_description": "Calculator addition adds positive numbers",
      "status": "passed",
      "file": "specs/calc-spec.raku",
      "line": 3,
      "duration": 0.001,
      "tags": []
    },
    {
      "description": "overflows on MAX_INT",
      "full_description": "Calculator addition overflows on MAX_INT",
      "status": "failed",
      "file": "specs/calc-spec.raku",
      "line": 5,
      "duration": 0.001,
      "failure": {
        "expectations": [
          {
            "file": "specs/calc-spec.raku",
            "line": 5,
            "given": 2147483648,
            "expected": -2147483648,
            "negated": false
          }
        ]
      }
    },
    {
      "description": "handles negative-zero",
      "status": "pending",
      "pending_reason": "not yet implemented",
      "file": "specs/calc-spec.raku",
      "line": 6
    },
    {
      "description": "subtracts a positive",
      "status": "passed",
      "file": "specs/calc-spec.raku",
      "line": 10,
      "duration": 0.001
    }
  ],
  "summary": {
    "total": 4,
    "passed": 2,
    "failed": 1,
    "pending": 1,
    "skipped": 0,
    "duration": 0.045
  },
  "summary_line": "4 examples, 1 failed, 1 pending, 2 passed"
}

JUnit XML, consumable by Jenkins, GitLab CI, CircleCI, and every dashboard that ingests the testsuites / testsuite / testcase schema. The describe/context chain joins into classname for hierarchical grouping.

<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="behave" tests="4" failures="1" errors="0" skipped="1" time="0.045">
  <testsuite name="calc-spec.raku" tests="4" failures="1" errors="0" skipped="1" time="0.045">
    <testcase classname="Calculator &gt; addition" name="adds positive numbers"
              file="specs/calc-spec.raku" line="3" time="0.001"/>
    <testcase classname="Calculator &gt; addition" name="overflows on MAX_INT"
              file="specs/calc-spec.raku" line="5" time="0.001">
      <failure type="Expectation" message="Expected 2147483648 to be -2147483648"><![CDATA[
specs/calc-spec.raku:5
  Expected: 2147483648
  to be:    -2147483648
      ]]></failure>
    </testcase>
    <testcase classname="Calculator &gt; addition" name="handles negative-zero"
              file="specs/calc-spec.raku" line="6" time="0">
      <skipped message="pending: not yet implemented"/>
    </testcase>
    <testcase classname="Calculator &gt; subtraction" name="subtracts a positive"
              file="specs/calc-spec.raku" line="10" time="0.001"/>
  </testsuite>
</testsuites>

Test Anything Protocol v13. Compatible with prove, tappy, and every TAP consumer. # TODO for pending, # SKIP for skipped. Pending examples are expected fails, not failures.

TAP version 13
1..4
ok 1 - Calculator addition adds positive numbers
not ok 2 - Calculator addition overflows on MAX_INT
  ---
  severity: 'fail'
  file: 'specs/calc-spec.raku'
  line: 5
  message: 'Expected 2147483648 to be -2147483648'
  got: '2147483648'
  expected: '-2147483648'
  ...
ok 3 - Calculator addition handles negative-zero # TODO not yet implemented
ok 4 - Calculator subtraction subtracts a positive

#write your own

Every formatter is a Raku class that composes the BDD::Behave::Formatter role. The role declares a hook for every interesting event the runner emits. All default to no-ops, so a custom formatter only overrides what it cares about.

use BDD::Behave::Formatter;
use BDD::Behave::Formatter::Registry;

class DotsFormatter does BDD::Behave::Formatter {
  method name(--> Str) { 'dots' }

  method example-pass($example)                   { print '.' }
  method example-fail($example, :$failure-info)   { print 'F' }
  method example-pending($example)                { print '*' }
  method example-skipped($example)                { print 'S' }
  method run-summary($result, *%) {
    say "";
    say "{$result.total} examples, {$result.failed} failed, {$result.passed} passed";
  }
}

BDD::Behave::Formatter::Registry.register('dots', DotsFormatter);

Once registered, the formatter is selectable like any built-in:

behave --format dots specs/
Hooks worth overriding. suite-start, group-start, example-pass/fail/pending/skipped, run-summary, and multi-file-overall are the most common. See the docs for the full lifecycle.