on
Procedural Macros, pt. 5: Test Cases
We are going to test the code from our previous post with a couple of different approaches.
synstructure::test_derive
is a simple macro that evaluates whether our derive
function generates the expected expansion for the macro’s invocation. It will
form a part of our unit tests.
We use the no_build
option to disable checking whether the code within the
macro compiles. While the code we have provided in the example above is fairly
self-contained and would compile, no_build
can be useful in other more
complicated scenarios.
Unfortunately, we can’t use a procedural macro within the same crate that
defines it. This means addition of unit tests that use our generated code would
fail. Instead, we are going to use crate
trybuild that provides a
nice test harness for procedural macros. trybuild
can be used to check if test
cases fail compilation as well - a feature we are going to leverage later (when
we add the ability to skip the generation of getters for a field).
Let’s start by adding trybuild
to our crates dev dependencies.
Let’s now create a folder tests/ui
inside our project’s root folder.
Additionally, let’s create a file compile_tests.rs
within. Edit
compile_tests.rs
to the following
This code initializes the trybuild
test harness. We then invoke it with a test
file that we expect to pass compilation. In contrast, to test for failure, we’d
invoke it with compile_fail
. To complete the test case, we need to provide the
content for tests_getters.rs
(placed in tests/ui
).
With cargo test
, our test harness will compile and run the code above -
expecting it to pass without errors. In the final installment to this series, we will add the
ability to skip the generation of a getter for a particular field - by the
inclusion of attributes on a field.