Crates.io | mos-test |
lib.rs | mos-test |
version | 0.0.1 |
source | src |
created_at | 2023-01-04 19:54:54.778831 |
updated_at | 2023-01-04 19:54:54.778831 |
description | custom test runner for rust-mos |
homepage | |
repository | https://github.com/mrk-its/mos-test |
max_upload_size | |
id | 751082 |
size | 20,371 |
mos-test
mos-test
is port of great defmt-test
to mos architecture. It is a alternative test harness that lets you write and run unit tests on all llvm-mos platforms as if you were using the built-in #[test]
attribute.
It is compatible with rust-analyzer's ▶ Run Test
button, which means you can run your tests straight from VS Code
For a full list of mos-test's capabilities, please refer to the documentation below.
mos-test
to an existing projectIf you want to add mos-test
to an existing Cargo project / package, for each crate that you want to test you need to do these changes in Cargo.toml
:
mos-test
as a dev-dependency
harness
to false
to disable the default test harness, the test
crate which depends on std
. examples below# Cargo.toml
# for the library crate (src/lib.rs)
[lib]
harness = false
# for the bin crate (src/main.rs)
[[bin]]
name = "binary_name"
harness = false
# for each crate in the `tests` directory
[[test]]
name = "test-name" # tests/test-name.rs
harness = false
[[test]]
name = "second" # tests/second.rs
harness = false
The other thing to be aware is that cargo test
will compile all crates in the package, or workspace.
This may include crates that you don't want to test, like src/main.rs
or each crate in src/bin
or examples
.
To identify which crates are being compiled by cargo test
, run cargo test -j1 -v
and look for the --crate-name
flag passed to each rustc
invocation.
To test only a subset of the crates in the package / workspace you have two options:
cargo test
. for example, cargo test --lib --test integration
tests two crates: the library crate (src/lib.rs
) and tests/integration.rs
cargo test
to test all crates that were not disabled.if you have this project structure
$ tree .
.
├── Cargo.toml
├── src
│ ├── lib.rs
│ └── main.rs
└── tests
└── integration.rs
and have src/lib.rs
set up for tests but don't want to test src/main.rs
you'll need to disable tests for src/main.rs
# Cargo.toml
[package]
# ..
name = "app"
[[bin]] # <- add this section
name = "app" # src/main.rs
test = false
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 function is called before each test case.
// It accesses the state created in `init`,
// though like with `test`, state access is optional.
#[before_each]
fn before_each(state: &mut super::MyState) {
defmt::println!("State flag before is {}", state.flag);
}
// This function is called after each test
#[after_each]
fn after_each(state: &mut super::MyState) {
defmt::println!("State flag after is {}", state.flag);
}
// 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)
state.flag = false;
}
}
$ cargo test -p testsuite
0.000000 (1/2) running `assert_true`...
└─ integration::tests::__defmt_test_entry @ tests/integration.rs:37
0.000001 State flag before is true
└─ integration::tests::before_each @ tests/integration.rs:26
0.000002 State flag after is true
└─ integration::tests::after_each @ tests/integration.rs:32
0.000003 (2/2) running `assert_flag`...
└─ integration::tests::__defmt_test_entry @ tests/integration.rs:43
0.000004 State flag before is true
└─ integration::tests::before_each @ tests/integration.rs:26
0.000005 State flag after is false
└─ integration::tests::after_each @ tests/integration.rs:32
0.000006 all tests passed!
└─ integration::tests::__defmt_test_entry @ tests/integration.rs:11
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, mos-test
supports a #[should_error]
attribute, which inverts the meaning of the returned TestOutcome
.
Err
makes the test pass, while Ok
/()
make it fail.
Licensed under either of
Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
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.