@@ -176,6 +176,8 @@ subcases that a Zephyr *ztest* test image will expose.
176176 high-level test project level, particularly when tests do too
177177 many things, is too vague.
178178
179+ There exist two alternatives to writing tests. The first, and more verbose,
180+ approach is to directly declare and run the test suites.
179181Here is a generic template for a test showing the expected use of
180182:func: `ztest_test_suite `:
181183
@@ -207,8 +209,91 @@ Here is a generic template for a test showing the expected use of
207209 ztest_run_test_suite(common);
208210 }
209211
212+ Alternatively, it is possible to split tests across multiple files using
213+ :func: `ztest_register_test_suite ` which bypasses the need for `extern `:
214+
215+ .. code-block :: C
216+
217+ #include <ztest.h>
218+
219+ void test_sometest1(void) {
220+ zassert_true(1, "true");
221+ }
222+
223+ ztest_register_test_suite(common, NULL,
224+ ztest_unit_test(test_sometest1)
225+ );
226+
227+ The above sample simple registers the test suite and uses a `NULL ` pragma
228+ function (more on that later). It is important to note that the test suite isn't
229+ directly run in this file. Instead two alternatives exist for running the suite.
230+ First, if to do nothing. A default :func: `test_main ` function is provided by
231+ ztest. This is the preferred approach if the test doesn't involve a state and
232+ doesn't require use of the pragma.
233+
234+ In cases of an integration test it is possible that some general state needs to
235+ be set between test suites. This can be thought of as a state diagram in which
236+ :func: `test_main ` simply goes through various actions that modify the board's
237+ state and different test suites need to run. This is achieved in the following:
238+
239+ .. code-block :: C
240+
241+ #include <ztest.h>
242+
243+ struct state {
244+ bool is_hibernating;
245+ bool is_usb_connected;
246+ }
247+
248+ static bool pragma_always(const void *state)
249+ {
250+ return true;
251+ }
252+
253+ static bool pragma_not_hibernating_not_connected(const void *s)
254+ {
255+ struct state *state = s;
256+ return !state->is_hibernating && !state->is_usb_connected;
257+ }
258+
259+ static bool pragma_usb_connected(const void *s)
260+ {
261+ return ((struct state *)s)->is_usb_connected;
262+ }
263+
264+ ztest_register_test_suite(baseline, pragma_always,
265+ ztest_unit_test(test_case0));
266+ ztest_register_test_suite(before_usb, pragma_not_hibernating_not_connected,
267+ ztest_unit_test(test_case1),
268+ ztest_unit_test(test_case2));
269+ ztest_register_test_suite(with_usb, pragma_usb_connected,,
270+ ztest_unit_test(test_case3),
271+ ztest_unit_test(test_case4));
272+
273+ void test_main(void)
274+ {
275+ struct state state;
276+
277+ /* Should run `baseline` test suite only. */
278+ ztest_run_registered_test_suites(&state);
279+
280+ /* Simulate power on and update state. */
281+ emulate_power_on();
282+ /* Should run `baseline` and `before_usb` test suites. */
283+ ztest_run_registered_test_suites(&state);
284+
285+ /* Simulate plugging in a USB device. */
286+ emulate_plugging_in_usb();
287+ /* Should run `baseline` and `with_usb` test suites. */
288+ ztest_run_registered_test_suites(&state);
289+
290+ /* Verify that all the registered test suites actually ran. */
291+ ztest_verify_all_registered_test_suites_ran();
292+ }
293+
210294 For *twister * to parse source files and create a list of subcases,
211- the declarations of :func: `ztest_test_suite ` must follow a few rules:
295+ the declarations of :func: `ztest_test_suite ` and
296+ :func: `ztest_register_test_suite ` must follow a few rules:
212297
213298- one declaration per line
214299
0 commit comments