Testing Your Embedded Rust (feat. embedded-hal-mock and explosions)
Let's say we have a device - it's a simple bounce-back machine. When you send a beep, it replies with a boop. This device is the Beep-Boop Box! 📦✨
In Rust, using
embedded-hal, we've connected to this machine and written a generic driver for it. Here's how it might look:
Oh no! It seems that we accidentally wrote to SPI twice. However, our device doesn't say what it'll do if that happens, nor does our program. There's no way for us to know!
Let's pretend we didn't catch the error, though. Maybe no one found this bug, setting many Beep-Boop Boxes on fire! That's scary.
Mocking Our Device
However, we don't have to wait for customers' systems to set on fire!
embedded-hal has a testing suite lovingly known as
embedded-hal-mock. It supports both 0.x and 1.x versions of
embedded-hal, so practically everyone can use it!
Its README describes the crate's goal best:
"The goal of the crate is to be able to test drivers in CI without having access to hardware." ~the
embedded-hal-mock does precisely that! By modeling each action you perform over SPI, I2C, etc., you can ensure that only the operations you expect to happen... happen. Each action is known as a
Transaction. You can read more in its documentation.
Thankfully, with this crate, we can express exactly what responses we expect to send and receive given some combination of IO. Let's take a look!
//! Tests module
Writing this code "for real," I carefully ran the test...
As you can see, the test caught the issue! We only asked the
mock to expect two operations: read and write. However, it found a second read instead. In the model we've created, that's always a no-no. 👋
Let's say we fixed the bug - how does our test feel now? 😳
We're golden! Our Beep-Boop customers are safe! I've used it in my crates, too, helping to ensure that nothing goes wrong without my CI (and thus, me) knowing!
This crate can supercharge your embedded Rust - notably when used alongside something like
defmt-test for your binaries!
As you can see, some of Rust's biggest strengths lie in its testing mechanics. Imagining how a device might work when writing a driver can be challenging. Luckily, with Rust, someone's always got your back. In this case, that's you!
If you haven't tried embedded Rust, I wholeheartedly recommend it. 🦀✨
Thanks for taking a look - good luck!