3 unstable releases

new 0.2.0 Feb 20, 2021
0.1.1 Dec 3, 2020
0.1.0 Nov 16, 2020

#77 in Embedded development

Download history 22/week @ 2020-11-11 21/week @ 2020-11-18 24/week @ 2020-11-25 438/week @ 2020-12-02 450/week @ 2020-12-09 157/week @ 2020-12-16 94/week @ 2020-12-23 417/week @ 2020-12-30 362/week @ 2021-01-06 233/week @ 2021-01-13 75/week @ 2021-01-20 157/week @ 2021-01-27 281/week @ 2021-02-03 252/week @ 2021-02-10 93/week @ 2021-02-17

1,002 downloads per month
Used in 2 crates

MIT/Apache

58KB
1K SLoC

defmt-test

a test harness for embedded devices

Basic usage

  1. If you don't have a project setup yet, start from the app-template, then proceed with step 3. If you have a project based on an old version of app-template then proceed with step 1.
  1. In the testsuite crate, add defmt-test to the dependencies:
 # testsuite/Cargo.toml

 [dependencies]
+ defmt-test = "0.1.0"
  1. Within the testsuite/tests/test.rs file, create a tests module and mark it with the #[defmt_test::tests] attribute. Within that module write std-like unit tests: functions marked with the #[test] attribute.
// testsuite/tests/test.rs

#[defmt_test::tests]
mod tests {
    #[test]
    fn assert_true() {
        assert!(true)
    }

    #[test]
    fn assert_false() {
        assert!(false, "TODO: write actual tests")
    }
}
  1. Run cargo test -p testsuite to run the unit tests
$ cargo test -p testsuite
(..)
0.000000 INFO  (1/2) running `assert_true`...
└─ test::tests::__defmt_test_entry @ tests/test.rs:7
0.000001 INFO  (2/2) running `assert_false`...
└─ test::tests::__defmt_test_entry @ tests/test.rs:7
0.000002 ERROR panicked at 'TODO: write actual tests', testsuite/tests/test.rs:16:9
└─ panic_probe::print_defmt::print @ (..omitted..)
stack backtrace:
   0: HardFaultTrampoline
      <exception entry>
   1: __udf
   2: cortex_m::asm::udf
        at (..omitted..)
   3: rust_begin_unwind
        at (..omitted..)
   4: core::panicking::panic_fmt
        at (..omitted..)
   5: core::panicking::panic
        at (..omitted..)
   6: test::tests::assert_false
        at tests/test.rs:16
   7: main
        at tests/test.rs:7
   8: ResetTrampoline
        at (..omitted..)
   9: Reset
        at (..omitted..)

NOTE unit tests will be executed sequentially

Adding state

An #[init] function can be written within the #[tests] module. This function will be executed before all unit tests and its return value, the test suite state, can be passed to unit tests as an argument.

// state shared across unit tests
struct MyState {
    flag: bool,
}

#[defmt_test::tests]
mod tests {
    #[init]
    fn init() -> super::MyState {
        // state initial value
        super::MyState {
            flag: true,
        }
    }

    // this unit test doesn't access the state
    #[test]
    fn assert_true() {
        assert!(true);
    }

    // but this test does
    #[test]
    fn assert_flag(state: &mut super::MyState) {
        assert!(state.flag)
    }
}
$ cargo test -p testsuite
0.000000 INFO  (1/2) running `assert_true`...
└─ test::tests::__defmt_test_entry @ tests/test.rs:11
0.000001 INFO  (2/2) running `assert_flag`...
└─ test::tests::__defmt_test_entry @ tests/test.rs:11
0.000002 INFO  all tests passed!
└─ test::tests::__defmt_test_entry @ tests/test.rs:11

Test Outcome

Test functions may either return () and panic on failure, or return any other type that implements the TestOutcome trait, such as Result.

This allows tests to indicate failure via Result, which allows using the ? operator to propagate errors.

Similar to Rust's built-in #[should_panic] attribute, defmt-test supports a #[should_error] attribute, which inverts the meaning of the returned TestOutcome. Err makes the test pass, while Ok/() make it fail.

Support

defmt-test is part of the Knurling project, Ferrous Systems' effort at improving tooling used to develop for embedded systems.

If you think that our work is useful, consider sponsoring it via GitHub Sponsors.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be licensed as above, without any additional terms or conditions.

Dependencies

~1–1.5MB
~34K SLoC