Skip to main content

Crate behave

Crate behave 

Source
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().

MatcherDescription
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_ofAll matchers must pass
any_ofAt least one must pass
not_matchingInverts 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::checkCollect result without stopping
SoftErrors::finishReport 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 tests
  • teardown { ... } — cleanup code that runs after each test
  • each [...] |args| { ... } — parameterized test generation
  • pending "name" { ... } — mark tests as ignored
  • focus "name" { ... } — mark tests with a __FOCUS__ prefix in generated names
  • tag "name1", "name2" — attach metadata tags for CLI filtering
  • xfail "name" { ... } — mark a test as expected-to-fail
  • matrix [...] x [...] |a, b| { ... } — Cartesian product test generation
  • tokio; — generate async tests (requires tokio feature)
  • timeout <ms>; — fail tests that exceed a deadline (inherits through nesting)
  • skip_when!(condition, "reason") — skip a test conditionally at runtime

§Feature Flags

FeatureDefaultDescription
stdYesStandard library support
cliNoEnables cargo-behave binary
colorNoANSI-colored diff output for assertion failures
regexNoto_match_regex and to_contain_regex matchers
tokioNoRe-exports tokio for tokio; async test generation
httpNoHTTP status code and header matchers
urlNoURL component matchers
jsonNoJSON value matchers

Modules§

clicli
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 Expectation capturing the expression and its value.
expect_match
Asserts that an expression matches a pattern, with optional guard.
expect_no_panicstd
Asserts that the given expression does not panic.
expect_panicstd
Asserts that the given expression panics.
skip_whenstd
Conditionally skips a test at runtime with a reason.

Structs§

Expectation
Wraps a value with metadata for expressive assertions.
MatchError
Error returned when an expectation matcher fails.
SoftErrorsstd
Collects MatchErrors from soft assertions and reports them together.
SoftMatchErrorstd
Error returned by SoftErrors::finish when assertions failed.

Traits§

BehaveMatch
Trait for implementing custom matchers.