Test Case
Overview
test_case
crate provides procedural macro attribute that generates parametrized test instances.
Getting Started
Crate has to be added as a dependency to Cargo.toml
:
[]
= "2.0.0-rc1"
and imported to the scope of a block where it's being called
(since attribute name collides with rust's built-in custom_test_frameworks
) via:
use test_case;
Example usage:
Output from cargo test
for this example:
; ; ; ;
Advanced use
For #[test_case(body)]
the body is built as follows:
body
:= $arguments ($expected_result)? ($description)?
Arguments
arguments
:= $expr(,$expr)*(,)?
Comma separated list of one or more expressions, eg.:
Expected result
expected_result
:= => ($modifier)* $validator
Optional part that provides assertions to instantiated tests.
When using expected_result
version of test_case
tested function must return a type
that can be matched with validator. Each validator description states how to ensure
that the type returned by function can be matched.
Modifiers
modifier
:= ignore | inconclusive
Both ignore
and inconclusive
keywords indicate that test case should be skipped. This is equivalent to using
#[ignore]
attribute on normal test. Eg.:
// not yet implemented
Validator
There are numerous validators provided by test_case
:
validator
:= $simple|$matching|$panicking|$with|$using|$complex
Simple
simple
:= $expr
Accepts any expression that evaluates to function return type and
compares it against whatever tested block returns via assert_eq
. Eg.:
Matching
matching
:= matches $pattern
A pattern following keyword matches
.
Result of a function is compared to pattern
via MatchExpression. Eg.:
Panicking
panicking
:= panics ($expr)?
Indicates that test instance should panic. Works identical to #[should_panic]
test attribute.
Optional expression after the keyword is treated like expected
in should_panic. Eg.:
With
with
:= with $closure
Allows manual assertions of the result of testing function. Closure must indicate argument type and it has to be implicitly convertible from type returned by testing function. Eg.:
Using
using
:= using $path
Work similar to with
attribute, with the difference being that instead of a closure
it accepts path to a function that should validate result of the testing function. Eg.:
Complex
complex
:= (it|is) $complex_expression
complex_expression
:= not $complex_expression_inner | $complex_expression_inner (and $complex_expression_inner)* | $complex_expression_inner (or $complex_expression_inner)*
complex_expression_inner
:= $cmp_assertion|$path_assertion|$collection_assertion|\($complex_expression\)
cmp_assertion
:= $ord_assertion|$almost_eq_assertion
path_assertion
:= existing_path|file|dir|directory
collection_assertion
:= contains $expr|contains_in_order $expr
ord_assertion
:= (eq|equal_to|lt|less_than|gt|greater_than|leq|less_or_equal_than|geq|greater_or_equal_than) $expr
almost_eq_assertion
:= (almost_equal_to|almost) $expr precision $expr
Complex assertions are created as an extension to test_case
allowing for more flexibility in comparisons. Eg.:
it
and is
have equivalent interpretation. Both variants exist in order to make test cases easier to read.
complex assertions are WIP content, use at own discretion.
Notes about async & additional attributes
If test_case
is used with async
tests, eg. #[tokio::test]
, or user wants to pass other attributes to each
test instance then additional attributes have to be added past first occurrence of #[test_case]
. Eg.:
async
License
Licensed under of MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
Contributing
Project roadmap is available at link. All contributions are welcome.
Recommended tools:
cargo readme
- to regenerate README.md based on template and lib.rs commentscargo insta
- to review test snapshotscargo edit
- to add/remove dependenciescargo fmt
- to format codecargo clippy
- for all insights and tipscargo fix
- for fixing warnings