Skip to content

Guides · 6 of 7

Tooling

Four tools around the suite: strict validation to catch a missing step at compile time, cargo-bdd to list what is registered, a language server for the editor, and report writers for CI.

Strict validation

By default a missing step is found when its scenario runs. The test fails and names the step, the feature, and the scenario:

tests/features/missing.feature
Feature: A forgotten step
  Scenario: Nobody wrote the bell
    Given a lantern on the trolley
    When the bell is rung twice
    Then the lantern arrives upright

Not part of the sample crate: it exists to fail.

cargo test --test missingexcerpt
thread 'nobody_wrote_the_bell' (605609) panicked at tests/missing.rs:9:1:
Step not found at index 1: When the bell is rung twice (feature: tests/features/missing.feature, scenario: Nobody wrote the bell)

Turn on the strict-compile-time-validation feature of rstest-bdd-macros and the same mistake stops the build, pointing at the #[scenario] that needs the step:

Terminal
$ cargo test --features "rstest-bdd-macros/strict-compile-time-validation"
Outputexcerpt
error: No matching step definition found for 'When the bell is rung twice'
 --> tests/missing.rs:9:1
  |
9 | #[scenario(path = "tests/features/missing.feature")]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

cargo-bdd

cargo-bdd builds the test binaries and asks each for the steps it registered. steps lists them with the file and line that define them:

Terminal
$ cargo install cargo-bdd --version 0.6.0 --locked
$ cargo-bdd steps
cargo-bdd steps, the first six linescargo-bdd 0.6.0
Given 'a bell on the trolley' (tests/bell.rs:15)
Then 'the rabbit hears {count:u32} rings' (tests/bell.rs:26)
When 'the bell rings {times:u32} times' (tests/bell.rs:21)
Given 'a trolley carrying {count:u32} lanterns' (tests/counting.rs:15)
Then '{count:u32} lanterns arrive at the picnic' (tests/counting.rs:25)
When 'the departure bell rings' (tests/counting.rs:20)

duplicates lists definitions that share a keyword and pattern. Across separate integration-test files, as in the sample crate, that is harmless: each file is its own test binary.

The language server

rstest-bdd-lsp speaks the Language Server Protocol over standard input and output. It jumps from a step definition to the feature lines it matches and back, and reports unimplemented steps, unused definitions, and mismatched placeholders, tables, and docstrings when a file is saved.

Terminal
$ cargo install --git https://github.com/leynos/rstest-bdd --tag v0.6.0 rstest-bdd-server --locked
$ rstest-bdd-lsp --help
rstest-bdd-lsp --helpexcerpt
Language server for rstest-bdd BDD testing framework

Usage: rstest-bdd-lsp [OPTIONS]

Options:
      --log-level 
          Log level (trace, debug, info, warn, error)

      --debounce-ms 
          Debounce interval in milliseconds for file change events

      --workspace-root 
          Override workspace root path for discovery.

Reports

Every scenario that runs records its outcome in the test process. rstest_bdd::reporting::json::write_snapshot writes those records as JSON to any io::Write, and reporting::junit::write_snapshot writes JUnit XML to any fmt::Write, with a <skipped> element and its reason for each skip. Feature paths in both are relative to the crate root.