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}