Expand description
An assertion library that uses types and data to fail tests instead of panicking.
I made this crate for a project I’m working on that’s #[no_std], has no allocator, uses a custom-built test framework, and has no support for unwinding. Assertions that panic are therefore undesirable, since panicking exits the test handler and will prevent further tests from running.
That said, this library still works for crates that use the standard test framework. Instead of returning () from tests, simply return impl Assertion:
#[test]
fn is_equal_to() -> impl Assertion {
assert_that!(1 + 2).is_equal_to(3)
}and the test framework will use the std::process::Termination implementation on Assertion to determine success or failure. The assert_that! macro also captures the exact location of its invocation, so error messages can still be descriptive.
There is also multi_assert!, which allows you to test multiple assertions at once:
#[test]
fn multi_assert() -> impl Assertion {
multi_assert!(
assert_that!(1 + 2).is_equal_to(3),
assert_that!(3 + 4).is_equal_to(7),
assert_that!(23).is_equal_to(10 * 2 + 3),
assert_that!(7).is_greater_than(5),
assert_that!(42).is_not_equal_to(6),
)
}Multi-assertions are not short-circuiting, so failed assertions will print all their errors:
#[test]
fn multi_assert_fail_messages() -> impl Assertion {
multi_assert!(
assert_that!(1 + 1).is_equal_to(2),
assert_that!(1 + 2).is_equal_to(2),
assert_that!(1 + 2).is_equal_to(4),
assert_that!(3 + 4).is_equal_to(7),
assert_that!(9 + 10).is_greater_than(23),
)
}assertion failures in a multi-assert:
0. [ok]
1. assertion starting at src/tests/multi.rs:42:9 failed: `lhs == rhs`
lhs: 3
rhs: 2
2. assertion starting at src/tests/multi.rs:43:9 failed: `lhs == rhs`
lhs: 3
rhs: 4
3. [ok]
4. assertion starting at src/tests/multi.rs:45:9 failed: `lhs > rhs`
lhs: 19
rhs: 23You can even use assertions of different types in multi-assertions using the #[dyn] attribute:
#[test]
fn multi_assert_dyn() -> impl Assertion {
multi_assert!(#[dyn] // <- casts assertions to `dyn Assertion`
assert_that!(1 + 2).is_equal_to(3), // <- BinaryAssertion<i32, i32>
assert_that!(true).is_true(), // <- UnaryAssertion<bool>
assert_that!(true).is_false().should_fail(), // <- ShouldFail<UnaryAssertion<bool>>
)
}§Feature flags
Support for std (and alloc) is provided by default, but these can be disabled with the std and alloc feature flags (where std implies alloc).
- Disabling
stdremoves thestd::process::Terminationrequirement and implementations forAssertion. It will not be possible to returnimpl Assertionfrom tests without this flag, however if you’re using a custom test framework you should be able to build around this. - Disabling
allocwill remove the ability to use the#[dyn]attribute inmulti_assert!, as it requiresBoxto work.
Re-exports§
Modules§
Macros§
- assert_
that - Construct the first part of an
Assertion. - fail
- Construct an
Assertionthat will always fail. - multi_
assert - Construct a group of assertions that will all be tested simultaneously. If one assertion fails, the group as a whole will fail.
- succeed
- Construct an
Assertionthat will always succeed.
Structs§
- Assert
- A wrapper around some object that can be reasoned about.
- Assert
Info - Information about an invocation of
assert_that!.