No-std testing
references :
Rust has a built in test framework. It helps in automating unit tests and integration tests.
But this framework is dependent on a library called "test". "test" is dependent on the std library.
Since we are working in a no-std environment, the default test-framework used by the rust compiler becomes unusable.
Some good news: Rust compiler gives you an option to use a custom test framework if you do not prefer to use the default std-dependent framework.
You have to activate the unstable feature called : custom-test-frameworks
The disadvantage compared to the default test framework is that many advanced features, such as should_panic tests, are not available. Instead, it is up to the custom implementation to provide such features itself if needed
The feature requires you to Define a runner function that takes in all of the test functions collected in the form as an array and executes them to your specification.
As seen, you can specify how the tests are run, which tests get to run, and how the test results get displayed. You are free to code the behavior of your test handler.
Steps to setup no-std tests
- Activate the feature across the entire crate by adding this attribute to the root of the crate (in our case, main.rs):
- Specify the path of the test runner function, describe this path crate-wise. To be specific, state the test runner in the root of the crate. The test runner function can be code found in another module. You can go wild
-
Set up display system. You can use your own machine drivers or an external console. Just find anway for print and println to work.
- Add println macro to your crate.
- Define a good panic handler function with println capabilities
-
Define the runner function. as follows :
- The test framework exports its entry point function as main(). But in this environmet, main is ignored. You need to intergrate the entry point of the test framework as part your current entry point.
So we make the test framework define its entry point with a name that we specify. Like this :
- call the entry_point function under your current program entry point. For Example
How to print test results
- define custom assert
- use procedural macros to print function name/ For now just write custom messages as demonsstrated in the RustConcepts place
How to run tests module-wise
The main runner function take in ALL functions that have the #[test_case] attribute.
What if you do not want to run all tests? What if you just want to run the tests of a certain module only?
Solution
Let us say that you have a module called "tv". The path to this module is "crate::tv".
"tv" module has an inner test module that declares test functions: "crate::tv::tests". The tests are unit tests.
the tv module has 3 functions :
- switch_on()
- switch_off()
- change_channel()
The unit test for the tv module has 3 tests:
- test_switch_on()
- test_switch_off()
- test_change_channel()
Here is the source file for the tests
If you run "cargo test" command, all three test functions will run. You then build a switch, as demonstrated below. We have also removed the #[test_case] attribute to the many functions. Now we have one place to control the tests of a single module:
To disable all tests of this module, remove the #[test_case] attribute from the switch.
To disable a particular test, comment it out inside the switch function
No-std Integration Tests
[undone] : Just Document the setup, not the actual tests. The actual tests specific to this project will be covered in the next chapters
An integration uses the crate an an external dependency. It depends on the std-dependent test framework. Since we cannot afford using that framework in a no-std environment, we manually set up complete new rust projects that depend on the "hobo-os" crate.
Steps to create an integration test binary :
- Next to the "Hobo-OS" directory, create a new binary crate using the "cargo new" command. eg App
- In the cargo.toml file, add the kernel as a dependency
- Copy the following files and folders from the Kernel folder into the App Folder.
- /.cargo
- hdd.dsk
- /src/lds
- Paste the template below into your main.rs file. Build on it however you want