Expand description
§behave
A BDD testing framework for Rust with a zero-keyword DSL.
behave provides a behave! macro for writing readable test suites and
an expect! macro for expressive assertions. Test suites compile to
standard #[test] functions — no custom test runner needed.
§Quick Start
use behave::prelude::*;
behave! {
"arithmetic" {
"addition" {
expect!(2 + 2).to_equal(4)?;
}
"subtraction" {
expect!(10 - 3).to_equal(7)?;
}
}
}Every matcher returns Result<(), MatchError>, so use ? to propagate
failures with clear diagnostics. When an assertion fails you see:
expect!(2 + 2)
actual: 4
expected: to equal 5§Matcher Reference
All matchers are methods on Expectation. Use expect! to create one.
Every matcher supports negation via .not().
| Matcher | Description |
|---|---|
| Equality | |
.to_equal(v) | Exact equality (==) |
.to_not_equal(v) | Exact inequality (!=) |
| Boolean | |
.to_be_true() | Value is true |
.to_be_false() | Value is false |
| Ordering | |
.to_be_greater_than(v) | Strictly greater |
.to_be_less_than(v) | Strictly less |
.to_be_at_least(v) | Greater or equal (>=) |
.to_be_at_most(v) | Less or equal (<=) |
.to_be_between(low, high) | Inclusive range check |
| Option | |
.to_be_some() | Value is Some(_) |
.to_be_none() | Value is None |
.to_be_some_with(v) | Value is Some(v) |
.to_be_some_and(f, desc) | Some(_) satisfying predicate |
| Result | |
.to_be_ok() | Value is Ok(_) |
.to_be_err() | Value is Err(_) |
.to_be_ok_with(v) | Value is Ok(v) |
.to_be_err_with(v) | Value is Err(v) |
.to_be_ok_and(f, desc) | Ok(_) satisfying predicate |
.to_be_err_and(f, desc) | Err(_) satisfying predicate |
Collections (Vec<T>, &[T]) | |
.to_contain(v) | Contains element |
.to_contain_all_of(&[..]) | Contains every element |
.to_be_empty() | Length is zero |
.to_not_be_empty() | Length is non-zero |
.to_have_length(n) | Exact length |
.to_all_satisfy(f, desc) | All elements match predicate |
.to_any_satisfy(f, desc) | At least one matches |
.to_none_satisfy(f, desc) | No elements match |
.to_contain_any_of(&[..]) | Contains at least one of |
| Strings | |
.to_start_with(s) | Has prefix |
.to_end_with(s) | Has suffix |
.to_contain_substr(s) | Contains substring |
.to_have_str_length(n) | Byte length |
.to_have_char_count(n) | Unicode character count |
.to_be_empty() | String is empty |
.to_not_be_empty() | String is non-empty |
.to_equal_ignoring_case(s) | ASCII case-insensitive equality |
| Floating-Point | |
.to_approximately_equal(v) | Within default epsilon |
.to_approximately_equal_within(v, e) | Within custom epsilon |
.to_be_nan() | Value is NaN |
.to_be_finite() | Not infinite, not NaN |
.to_be_infinite() | Positive or negative infinity |
.to_be_positive() | Strictly greater than zero |
.to_be_negative() | Strictly less than zero |
Sequences (Vec<T>, &[T]) | |
.to_contain_exactly(&[..]) | Exact ordered match |
.to_contain_exactly_in_any_order(&[..]) | Same elements, any order |
.to_start_with_elements(&[..]) | Prefix match |
.to_end_with_elements(&[..]) | Suffix match |
.to_be_sorted() | Non-descending order |
.to_be_sorted_by_key(f, desc) | Sorted by extracted key |
Sets (HashSet, BTreeSet) | |
.to_contain(&v) | Set has element |
.to_be_subset_of(&set) | All elements in other set |
.to_be_superset_of(&set) | Contains all from other set |
Paths (PathBuf, &Path) | |
.to_exist() | Path exists on filesystem |
.to_be_a_file() | Is a regular file |
.to_be_a_directory() | Is a directory |
.to_have_extension(ext) | Has file extension |
.to_have_file_name(name) | Has file name |
Regex (requires regex feature) | |
.to_match_regex(pat) | Full-string regex match |
.to_contain_regex(pat) | Substring regex match |
JSON (requires json feature) | |
.to_have_field(f) | Object has key |
.to_have_field_value(f, v) | Key has specific value |
.to_be_json_superset_of(v) | Recursive partial match |
HTTP (requires http feature) | |
.to_be_success() | Status 2xx |
.to_be_redirect() | Status 3xx |
.to_be_client_error() | Status 4xx |
.to_be_server_error() | Status 5xx |
.to_have_status_code(n) | Exact status code |
.to_have_header(name) | Header present |
.to_have_header_value(name, val) | Header has value |
URL (requires url feature) | |
.to_have_scheme(s) | URL scheme |
.to_have_host(h) | URL host |
.to_have_path(p) | URL path |
.to_have_query_param(k) | Query param exists |
.to_have_query_param_value(k, v) | Query param has value |
.to_have_fragment(f) | URL fragment |
| Display / Debug | |
.to_display_as(s) | Display output matches |
.to_display_containing(s) | Display output contains substring |
.to_debug_containing(s) | Debug output contains substring |
| Duration | |
.to_be_shorter_than(d) | Duration less than bound |
.to_be_longer_than(d) | Duration greater than bound |
.to_be_close_to_duration(d, tol) | Within tolerance of expected |
| Error Chain | |
.to_have_source() | Error has a source |
.to_have_source_containing(s) | Source message contains substring |
| General | |
.to_satisfy(f, desc) | Custom predicate function |
.to_match(m) | Custom BehaveMatch impl |
expect_panic! | Expression panics |
expect_no_panic! | Expression does not panic |
expect_match! | Matches a pattern |
Composition (combinators) | |
all_of | All matchers must pass |
any_of | At least one must pass |
not_matching | Inverts one matcher |
Map (HashMap, BTreeMap) | |
.to_contain_key(k) | Map has key |
.to_contain_value(v) | Map has value |
.to_contain_entry(k, v) | Map has key-value pair |
Soft Assertions (SoftErrors) | |
SoftErrors::check | Collect result without stopping |
SoftErrors::finish | Report all collected failures |
§Negation
Any matcher can be negated with .not() or
.negate():
use behave::prelude::*;
expect!(42).not().to_equal(99)?;
expect!(vec![1, 2]).not().to_contain(9)?;Negated failures read naturally:
expect!(value)
actual: 42
expected: not to equal 42§DSL Features
The behave! macro supports these constructs:
setup { ... }— shared setup code inherited by nested teststeardown { ... }— cleanup code that runs after each testeach [...] |args| { ... }— parameterized test generationpending "name" { ... }— mark tests as ignoredfocus "name" { ... }— mark tests with a__FOCUS__prefix in generated namestag "name1", "name2"— attach metadata tags for CLI filteringxfail "name" { ... }— mark a test as expected-to-failmatrix [...] x [...] |a, b| { ... }— Cartesian product test generationtokio;— generate async tests (requirestokiofeature)timeout <ms>;— fail tests that exceed a deadline (inherits through nesting)skip_when!(condition, "reason")— skip a test conditionally at runtime
§Feature Flags
| Feature | Default | Description |
|---|---|---|
std | Yes | Standard library support |
cli | No | Enables cargo-behave binary |
color | No | ANSI-colored diff output for assertion failures |
regex | No | to_match_regex and to_contain_regex matchers |
tokio | No | Re-exports tokio for tokio; async test generation |
http | No | HTTP status code and header matchers |
url | No | URL component matchers |
json | No | JSON value matchers |
Modules§
- cli
cli - CLI runner for
cargo-behave. - combinators
- Matcher combinators for composing multiple matchers.
- prelude
- Prelude module that re-exports everything needed for writing tests.
Macros§
- behave
- Defines BDD-style test suites using a zero-keyword DSL.
- expect
- Creates an
Expectationcapturing the expression and its value. - expect_
match - Asserts that an expression matches a pattern, with optional guard.
- expect_
no_ panic std - Asserts that the given expression does not panic.
- expect_
panic std - Asserts that the given expression panics.
- skip_
when std - Conditionally skips a test at runtime with a reason.
Structs§
- Expectation
- Wraps a value with metadata for expressive assertions.
- Match
Error - Error returned when an expectation matcher fails.
- Soft
Errors std - Collects
MatchErrors from soft assertions and reports them together. - Soft
Match Error std - Error returned by
SoftErrors::finishwhen assertions failed.
Traits§
- Behave
Match - Trait for implementing custom matchers.