avr-hal-template icon indicating copy to clipboard operation
avr-hal-template copied to clipboard

HOWTO: cargo test

Open cdaringe opened this issue 2 years ago • 5 comments

problem

I want to author unit tests, but doing so with no_std seems to introduce some problemos.

discussion

I read that #![cfg_attr(not(test), no_std)] may be a winning ticket to get std in test config, which makes sense.

However, you start to encounter some other (surely surmountable issues), e.g.

error[E0152]: duplicate lang item in crate `core` (which `rustc_std_workspace_core` depends on): `sized`.
  |
  = note: the lang item is first defined in crate `core` (which `void` depends on)
  = note: first definition in `core` loaded from /Users/cdaringe/src/nano-turret/target/avr-atmega328p/debug/deps/libcore-cb83c61aa17b09d5.rmeta
  = note: second definition in `core` loaded from /Users/cdaringe/src/nano-turret/target/avr-atmega328p/debug/deps/libcore-bf1da146ad2692e6.rmeta

Would be killer if the template was cargo test ready!

cdaringe avatar Jan 06 '24 02:01 cdaringe

Hm, do you intend to write unit tests that run on your host system (= the development machine) or on the target system (the AVR microcontroller)?

Rahix avatar Jan 06 '24 15:01 Rahix

Host system, CI, etc.

cdaringe avatar Jan 06 '24 16:01 cdaringe

The problem is that you are using the cargo configuration for AVR and that of course does not build something you can run on your host system (without an AVR simulator). The config is in .cargo/config.toml.

The cleanest solution to this problem is, in my eyes, to split your application into a library crate which contains everything that's platform independent and a firmware crate which pulls in the library crate and "connects" it to the actual hardware peripherals. Your unit tests are then just a part of the library crate.

Rahix avatar Jan 06 '24 20:01 Rahix

right. i'm still a noob. .cargo/config.toml applies to the whole project, but i was hoping that, if theres not a great way to do this all intra crate, that perhaps i'd at least be able to do it in a workspace? any ideas on how to make that work? sorry if you think it's outta scope for the template. i dunno--testing seems important enough to include in the recipe imho!

cdaringe avatar Jan 07 '24 00:01 cdaringe

Unfortunately, you've just discovered a big limitation of how cargo works at the moment. You can't do this well in a workspace either. The best bet you have is structuring your project like this:

+-my-avr-project/
  +-project-lib/
  | +-src/
  | | +-lib.rs
  | +-tests/
  | +-Cargo.toml
  +-project-firmware/
    +-.cargo/
    | +-config.toml
    +-src/
    | +-main.rs
    +-Cargo.toml       # has a dependency `project-lib = {path = "../project-lib/"}`

Then you have to cd into project-lib/ to run cargo test and into project-firmware/ for cargo run. I know this isn't particularly nice :(


sorry if you think it's outta scope for the template. i dunno--testing seems important enough to include in the recipe imho!

If it wasn't this unwieldy to implement, I'd gladly make the template support it. But as it stands, I think the additional complexity is not worth it...

In general, writing tests for embedded projects is a particularly difficult topic because you quickly hit limitations of what you can test outside of the real hardware environment. In practice (if tests are implemented at all), you'd build a sort of second firmware which just runs a number of tests on the hardware and then reports results e.g. over serial console.

Rahix avatar Jan 07 '24 11:01 Rahix