From 7f3f2782e5d058df2b249757baac2aa50f73a6aa Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Tue, 10 Dec 2019 13:18:26 -0800 Subject: docs: Add unit test documentation BRANCH=none BUG=none TEST=view in gitiles Change-Id: I4c282ed8bb831afa534e1c40bc619cd8e6d772ad Signed-off-by: Tom Hughes Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1958255 Commit-Queue: Jett Rink Reviewed-by: Jett Rink --- docs/fingerprint/fingerprint.md | 20 +----- docs/sitemap.md | 4 ++ docs/unit_tests.md | 135 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+), 17 deletions(-) create mode 100644 docs/unit_tests.md (limited to 'docs') diff --git a/docs/fingerprint/fingerprint.md b/docs/fingerprint/fingerprint.md index b92559acf6..899344232f 100644 --- a/docs/fingerprint/fingerprint.md +++ b/docs/fingerprint/fingerprint.md @@ -95,23 +95,7 @@ prevent you from uploading. ## Building and running unit tests -List available unit tests: - -```bash -(chroot) ~/trunk/src/platform/ec $ make print-host-tests -``` - -Build and run a specific unit test: - -```bash -(chroot) ~/trunk/src/platform/ec $ make run-fpsensor -``` - -Build and run all unit tests: - -```bash -(chroot) ~/trunk/src/platform/ec $ make runhosttests -j -``` +See the [Unit Tests] documentation for details on how to [run the unit tests]. ## Build ectool @@ -449,3 +433,5 @@ detail. [firmware ebuild]: https://chrome-internal.googlesource.com/chromeos/overlays/chromeos-overlay/+/refs/heads/master/chromeos-base/chromeos-firmware-fpmcu/chromeos-firmware-fpmcu-9999.ebuild#40 [`chromeos-fpmcu-release*` ebuilds]: https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/master/sys-firmware [internal manifest]: https://chromium.googlesource.com/chromiumos/docs/+/master/developer_guide.md#get-the-source-code +[Unit Tests]: ../unit_tests.md +[run the unit tests]: ../unit_tests.md#running diff --git a/docs/sitemap.md b/docs/sitemap.md index c92df06489..f80b7501b0 100644 --- a/docs/sitemap.md +++ b/docs/sitemap.md @@ -21,6 +21,10 @@ * [Fingerprint Authentication Design Doc](./fingerprint/fingerprint-authentication-design-doc.md) * [Fingerprint Factory Requirements](./fingerprint/fingerprint-factory-requirements.md) +## Testing + +* [Unit Tests](./unit_tests.md) + ## Updaters * [USB Updater](./usb_updater.md) diff --git a/docs/unit_tests.md b/docs/unit_tests.md new file mode 100644 index 0000000000..90312dbbdf --- /dev/null +++ b/docs/unit_tests.md @@ -0,0 +1,135 @@ +# Unit Tests + +Provides an overview of how to write and run the unit tests in the EC codebase. + +[TOC] + +## Running Unit Tests {#running} + +The unit tests run on the host machine using the [`host` board]. + +List available unit tests: + +```bash +(chroot) ~/trunk/src/platform/ec $ make print-host-tests +``` + +Build and run a specific unit test (the `host_command` test in this example): + +```bash +(chroot) ~/trunk/src/platform/ec $ make run-host_command +``` + +Build and run all unit tests: + +```bash +(chroot) ~/trunk/src/platform/ec $ make runhosttests -j +``` + +## Writing Unit Tests + +Unit tests live in the [`test`] subdirectory of the CrOS EC codebase. + +Test-related macros (e.g., `TEST_EQ`, `TEST_NE`) and functions are defined in +[`test_util.h`]. + +`test/my_test.c`: + +```c +#include +#include "test_util.h" + +static bool some_function(void) +{ + return true; +} + +/* Write a function with the following signature: */ +test_static int test_my_function(void) +{ + /* Run some code */ + bool condition = some_function(); + + /* Check that the expected condition is correct. */ + TEST_EQ(condition, true, "%d"); + + return EC_SUCCESS; +} +``` + +`test/my_test.c`: + +```c +/* The test framework will call the function named "run_test" */ +void run_test(void) +{ + /* Each unit test can be run using the RUN_TEST macro: */ + RUN_TEST(test_my_function); + + /* Report the results of all the tests at the end. */ + test_print_result(); +} +``` + +Create a `tasklist` file for you test that lists the tasks that should run as +part of the test: + +`test/my_test.tasklist`: + +```c +/* + * No test task in this case, but you can use `TASK_TEST` macro to specify one. + */ +#define CONFIG_TEST_TASK_LIST +``` + +Add the test to the `Makefile`: + +`test/build.mk`: + +```Makefile +test-list-host += my_test +``` + +Make sure you test shows up in the "host" tests: + +```bash +(chroot) $ make print-host-tests | grep my_test +host-my_test +run-my_test +``` + +Build and run the test: + +```bash +(chroot) $ make run-my_test +``` + +*** note +**TIP**: Unit tests should be independent from each other as much as possible. +This keeps the test (and any system state) simple to reason about and also +allows running unit tests in parallel. You can use the +[`before_test` hook][`test_util.h`] to reset the state before each test is run. +*** + +## Mocks + +[Mocks][`mock`] enable you to simulate behavior for parts of the system that +you're not directly testing. They can also be useful for testing specific edge +cases that are hard to exercise during normal use (e.g., error conditions). + +See the [Mock README] for details. + +### Mock Time + +When writing unit tests that rely on a clock, it's best not to rely on a real +hardware clock. It's very difficult to enforce exact timing with a real clock, +which leads to test flakiness (and developers ignoring tests since they're flaky +). Instead, use the [Mock Timer] to adjust the time during the test. + +[`mock`]: /include/mock +[Mock Timer]: /include/mock/timer_mock.h +[`test`]: /test +[`host` board]: /board/host/ +[`test_util.h`]: /include/test_util.h +[Mock README]: /common/mock/README.md -- cgit v1.2.1