> Where possible, and where it makes sense, you should try to test as much as possible on your host machine, not on the target device.
When I have tried this I have encountered multiple problems, first that the Rust test framework requires std, making it convoluted writing test code – but when working around that using conditional compilation, I run into other things like the `esp-hal` depending on crates that won't compile on the host.
I do something similar. I have all my esp/idf code in one crate and all my business logic in a separate crate. The business crate has no dependencies that won’t compile/run on the host. This is where all my tests live.
This is good advice however it should be noted that many of espressif's other purely software components depend on esp-hal, so you still want it to compile if you use any of espressif's provided components.
Why would that be? one of the nice features of the sans-io pattern is that it seperates your HAL from the program itself; if your state machine says "send a network packet", send it using embassy (or tokio or bsd-sockets or whatever). The underlying libraries have little or no bearing on "write your program as a big synchronous state-machine"
same goes for "wait 10 ms" or "change this gpio pin".
I don't use the the builtin testing framework, or std, and I often explicitly use a no-heap crate. Check out Embassy and you'll be free to ignore pretty almost everything suggested here, especially when developing and testing. I create a separate [bin] for each test (I usually run out of flash to fit all the tests into a single binary), and a few lines of bash/python to make a test runner/reporter for all the flashing and running of tests. Sometimes I flash up to 50 times a day and haven't lost an MCU (AVR-Rust, ESP-Rust, STM-Rust) yet due to too many writes.
Test code doesn't need to live on the device itself. You can call no_std code from std code and tell the compiler "hey, this code is only ran on hosts that have access to std" without trying to bundle the std library into your no_core code. You're not going to able to test I/O (does this function actually set Pin0 to HIGH or LOW) but you can test logic.
This is a constant issue for me in every facet of embedded development - with the sole exception of devices that can easily be tested in a qemu environment.
I would also love to hear that the authors of this book suggest.
> Where possible, and where it makes sense, you should try to test as much as possible on your host machine, not on the target device.
When I have tried this I have encountered multiple problems, first that the Rust test framework requires std, making it convoluted writing test code – but when working around that using conditional compilation, I run into other things like the `esp-hal` depending on crates that won't compile on the host.
What is the recommended way to test on the host?