Skip to main content

os_test_framework/
lib.rs

1//! # os-test-framework
2//!
3//! Test framework for embedded systems and OS kernels.
4//!
5//! `os-test-framework` requires `alloc`, so your kernel will need a `global-allocator`.
6//!
7//! ## Getting Started
8//!
9//! First, enable `custom_test_frameworks`, set `test_runner` as the test runner
10//! from `os-test-framework`, and `reexport_test_harness_main`.
11//!
12//! ```rust,ignore
13//! #![feature(custom_test_frameworks)]
14//! #![reexport_test_harness_main = "test_main"]
15//! #![test_runner(os_test_framework::run_tests)]
16//! ```
17//!
18//! Implement `Platform`. The framework writes output through
19//! `Platform::print` and finishes the run through `Platform::exit`:
20//!
21//! ```rust,ignore
22//! use core::fmt::Arguments;
23//! use os_test_framework::{ExitState, Platform};
24//!
25//! struct MyPlatform;
26//!
27//! impl Platform for MyPlatform {
28//!     fn print(&mut self, args: Arguments) {
29//!         let _ = args;
30//!         todo!()
31//!     }
32//!
33//!     fn exit(&self, state: ExitState) -> ! {
34//!         match state {
35//!             ExitState::Success => todo!(),
36//!             ExitState::Failed => todo!(),
37//!         }
38//!     }
39//! }
40//! ```
41//!
42//! Call `init_platform` with your `Platform`, and `test_main` from your kernel
43//! entry point:
44//!
45//! ```rust,ignore
46//! use os_test_framework::init_platform;
47//!
48//! fn kernel_entry() {
49//!     init_platform(MyPlatform);
50//!     test_main();
51//! }
52//! ```
53//!
54//! Forward panics from your OS to `os-test-framework`:
55//!
56//! ```rust,ignore
57//! os_test_framework::forward_panic!();
58//! ```
59//!
60//! ## Adding A Test
61//!
62//! You can declare tests like this:
63//!
64//! ```rust,ignore
65//! use os_test_framework::test;
66//!
67//! test!(hello);
68//! fn hello() {
69//!     assert!(true);
70//! }
71//! ```
72//!
73//! You can add multiple tests in the same file:
74//!
75//! ```rust,ignore
76//! use os_test_framework::test;
77//!
78//! test!(hello);
79//! fn hello() {
80//!     assert!(true);
81//! }
82//!
83//! test!(hello2);
84//! fn hello2() {
85//!     assert!(true);
86//! }
87//! ```
88#![no_std]
89
90use owo_colors::OwoColorize;
91
92extern crate alloc;
93
94mod panic;
95mod platform;
96#[doc(hidden)]
97pub mod __private {
98    pub use crate::_run_test;
99    pub use crate::printing::_print;
100}
101
102pub use crate::{panic::*, platform::*};
103
104mod make_test;
105mod printing;
106
107pub fn run_tests(tests: &[&dyn Fn()]) -> ! {
108    let test_count = tests.len();
109
110    println!("\nrunning {} tests", test_count);
111
112    for test in tests {
113        test()
114    }
115
116    println!();
117    println!(
118        "test result: {}. {} passed; 0 failed",
119        "ok".green(),
120        test_count
121    );
122    println!();
123
124    platform().lock().exit(ExitState::Success);
125}
126
127#[doc(hidden)]
128pub fn _run_test(name: &str, func: fn()) {
129    print!("test {} ...", name);
130    func();
131    println!(" {}", "ok".green());
132}