Expand description
Isotest enables a very specific Rust unit testing pattern.
Say you have some complex data type which is used in a lot of places. You’d like to write functions that operate on that complex data, but these functions only need to know about some small subset of that data type. It could be convenient to write those functions generically over a trait which contains methods that work with that subset of data, rather than taking the full data type.
There a few key benefits to doing this. Using a trait hides irrelevant details, keeping the concern of the function limited to only what it needs to know. This is a good application of the principle of least privilege.
Using a trait also makes writing tests easier. If we used the full data type, we would need to create test fixtures with a lot of extraneous arbitrary data which won’t even affect the function under test. By using a trait, we can write a much simpler test-only data structure which implements the same trait, and use that instead of the complex “real” data type in our tests. This keeps tests simpler and avoids the need to generate lots of arbitrary throw-away data.
Additionally, when debugging a failing test, it’s a lot easier to get debug output on just the data we care about, and not have all of the noise of the real data structure included in the debug output.
The only concern with this approach is that we’re not testing the “real” data, and if there
is any problem with our test data type or its implementation of the common trait, then
we may not be testing what we think we are testing. This is where isotest
comes in.
isotest
helps ensure that our implementation of the common trait is correct by
letting the user define functions to convert to and from the test data type, and
then providing a macro with a simple API to run tests for both types.
The user can write tests in terms of the simpler test data, but then that test gets run
for both test and real data, to ensure that assumptions implicit in the trait implementation
are not faulty. Thus, you get the benefit of simplifying your test writing while
still testing your logic with real data.
Re-exports§
pub use paste;
Macros§
- iso
- Helper to define a two-way
Iso
relationship between test data and real data. - isotest
- Run the same closure for both the Test and Real versions of some data.
- isotest_
async - A version of
isotest!
which returnsFuture<Output = ()>
instead of()
and supportsasync
syntax.
Structs§
- IsoReal
Api - The API passed into an isotest in the Real context.
- IsoTest
Api - The API passed into an isotest in the Test context.
Enums§
- Isotest
Context - Which of the two contexts each isotest body will run under.
Traits§
- Iso
- Trait that declares the relationship between a “test” and “real struct”, namely how to go back and forth between the two.
Functions§
- assert_
iso_ invariants_ real - Test the invariants of your Iso implementation. This test must pass for any Real value you use.
- assert_
iso_ invariants_ test - Test the invariants of your Iso implementation. This test must pass for any Test value you use.
- roundtrip_
real - Roundtrip from real -> test -> real -> test, returning the two test items
- roundtrip_
test - Roundtrip from test -> real -> test
Type Aliases§
- Create
Real - Create function for the real context
- Create
Test - Creation function for the test context
- Modify
- The argument to an isotest
update
function - Update
Real - Update function for the real context
- Update
Test - Update function for the test context