It’s worth discussing trait level design-by-contract or trait integration test consisting of two features:
- permit
#[test]
on inherent and trait methods that do not require arguments and - provide a
#[required_of_client]
attribute for traitimpl
s.
Right now, you could add macros that generate test code to test trait impl
s, but they must be called manually. If you wanted to enforce it, then you’d need something more:
pub trait Foo {
fn foo(&self);
}
#[cfg(test)]
pub trait FooTester : Foo {
#[cfg(test)]
fn test_new() -> Box<Self>;
}
#[cfg(test)]
mod test {
#[require_of_client]
impl<F: Foo> FooTester for F;
impl<F: Foo> F {
#[test]
fn do_foo_test() {
let me = test_new();
...
}
}
} // mod test
In this, the #[require_of_client]
demands the impl exist but does not provide test_new
itself. Also F::do_foo_test()
is an inherent method for any Foo
that only exists here and becomes a test.
You might need the #[test]
to appear inside the FooTester
trait sometimes trait too. I used Box<Self>
here so that test_new
need not be Sized
, but maybe some use cases still need it, like tests in no_std
.