docs: ztest: Update documentation for new API

Documentation now includes:
- How to create a test suite
- How to use predicates
- How to use setup/before/after/teardown
- How to use test rules
- Direct people to use FFF instead of ztest mock

Fixes #47420

Signed-off-by: Yuval Peress <peress@google.com>
This commit is contained in:
Yuval Peress 2022-07-06 21:24:42 -06:00 committed by Fabio Baltieri
commit b513e621b0
4 changed files with 524 additions and 293 deletions

View file

@ -10,3 +10,4 @@ Testing
twister
coverage
sparse
ztest_deprecated

View file

@ -10,6 +10,171 @@ test structure.
The framework can be used in two ways, either as a generic framework for
integration testing, or for unit testing specific modules.
To enable the latest APIs of Ztest simply set :kconfig:option:`CONFIG_ZTEST_NEW_API=y`. The legacy
APIs will soon be deprecated and eventually removed.
Creating a test suite
*********************
Using Ztest to create a test suite is as easy as calling the :c:macro:`ZTEST_SUITE`. The macro
accepts the following arguments:
* ``suite_name`` - The name of the suite. This name must be unique within a single binary.
* :c:type:`ztest_suite_predicate_t` - An optional predicate function to allow choosing when the
test will run. The predicate will get a pointer to the global state passed in through
:c:func:`ztest_run_all` and should return a boolean to decide if the suite should run.
* :c:type:`ztest_suite_setup_t` - An optional setup function which returns a test fixture. This
will be called and run once per test suite run.
* :c:type:`ztest_suite_before_t` - An optional before function which will run before every single
test in this suite.
* :c:type:`ztest_suite_after_t` - An optional after function which will run after every single
test in this suite.
* :c:type:`ztest_suite_teardown_t` - An optional teardown function which will run at the end of
all the tests in the suite.
Below is an example of a test suite using a predicate::
#include <zephyr/ztest.h>
#include "test_state.h"
static bool predicate(const void *global_state)
{
return ((const struct test_state*)global_state)->x == 5;
}
ZTEST_SUITE(alternating_suite, predicate, NULL, NULL, NULL, NULL);
Adding tests to a suite
***********************
There are 4 macros used to add a test to a suite, they are:
* :c:macro:`ZTEST` ``(suite_name, test_name)`` - Which can be used to add a test by ``test_name`` to a
given suite by ``suite_name``.
* :c:macro:`ZTEST_USER` ``(suite_name, test_name)`` - Which behaves the same as :c:macro:`ZTEST`, only
that when :kconfig:option:`CONFIG_USERSPACE` is enabled, then the test will be run in a userspace
thread.
* :c:macro:`ZTEST_F` ``(suite_name, test_name)`` - Which behaves the same as :c:macro:`ZTEST`, only
that the test function will already include a variable named ``fixture`` with the type
``<suite_name>_fixture``.
* :c:macro:`ZTEST_USER_F` ``(suite_name, test_name)`` - Which combines the fixture feature of
:c:macro:`ZTEST_F` with the userspace threading for the test.
Test fixtures
=============
Test fixtures can be used to help simplify repeated test setup operations. In many cases, tests in
the same suite will require some initial setup followed by some form of reset between each test.
This is achieved via fixtures in the following way::
#include <zephyr/ztest.h>
struct my_suite_fixture {
size_t max_size;
size_t size;
uint8_t buff[1];
};
static void *my_suite_setup(void)
{
/* Allocate the fixture with 256 byte buffer */
struct my_suite_fixture *fixture = k_malloc(sizeof(struct my_suite_fixture) + 255);
zassume_not_null(fixture, NULL);
fixture->max_size = 256;
return fixture;
}
static void my_suite_before(void *f)
{
struct my_suite_fixture *fixture = (struct my_suite_fixture *)f;
memset(fixture->buff, 0, fixture->max_size);
fixture->size = 0;
}
static void my_suite_teardown(void *f)
{
k_free(f);
}
ZTEST_SUITE(my_suite, NULL, my_suite_setup, my_suite_before, NULL, my_suite_teardown);
ZTEST_F(my_suite, test_feature_x)
{
zassert_equal(0, fixture->size);
zassert_equal(256, fixture->max_size);
}
Advanced features
*****************
Test rules
==========
Test rules are a way to run the same logic for every test and every suite. There are a lot of cases
where you might want to reset some state for every test in the binary (regardless of which suite is
currently running). As an example, this could be to reset mocks, reset emulators, flush the UART,
etc.
.. code-block:: C
#include <zephyr/fff.h>
#include <zephyr/ztest.h>
#include "test_mocks.h"
DEFINE_FFF_GLOBALS;
DEFINE_FAKE_VOID_FUN(my_weak_func);
static void fff_reset_rule_before(const struct ztest_unit_test *test, void *fixture)
{
ARG_UNUSED(test);
ARG_UNUSED(fixture);
RESET_FAKE(my_weak_func);
}
ZTEST_RULE(fff_reset_rule, fff_reset_rule_before, NULL);
A custom ``test_main``
======================
While the Ztest framework provides a default :c:func:`test_main` function, it's possible that some
applications will want to provide custom behavior. This is particularly true if there's some global
state that the tests depend on and that state either cannot be replicated or is difficult to
replicate without starting the process over. For example, one such state could be a power sequence.
Assuming there's a board with several steps in the power-on sequence a test suite can be written
using the ``predicate`` to control when it would run. In that case, the :c:func:`test_main`
function can be written as following::
#include <zephyr/ztest.h>
#include "my_test.h"
void test_main(void)
{
struct power_sequence_state state;
/* Only suites that use a predicate checking for phase == PWR_PHASE_0 will run. */
state.phase = PWR_PHASE_0;
ztest_run_test_suites(&state);
/* Only suites that use a predicate checking for phase == PWR_PHASE_1 will run. */
state.phase = PWR_PHASE_1;
ztest_run_test_suites(&state);
/* Only suites that use a predicate checking for phase == PWR_PHASE_2 will run. */
state.phase = PWR_PHASE_2;
ztest_run_test_suites(&state);
/* Check that all the suites in this binary ran at least once. */
ztest_verify_all_test_suites_ran();
}
Quick start - Integration testing
*********************************
@ -79,17 +244,12 @@ An example can be seen below::
*
* This test verifies the zassert_true macro.
*/
static void test_assert(void)
ZTEST(my_suite, test_assert)
{
zassert_true(1, "1 was false");
}
The above test is then enabled as part of the testsuite using::
ztest_unit_test(test_assert)
Listing Tests
=============
@ -104,6 +264,7 @@ can list all kernel test cases, for example, by entering::
twister --list-tests -T tests/kernel
Skipping Tests
==============
@ -113,43 +274,28 @@ report them as being skipped. Because the test inventory and
the list of tests is extracted from the code, adding
conditionals inside the test suite is sub-optimal. Tests that need
to be skipped for a certain platform or feature need to explicitly
report a skip using :c:func:`ztest_test_skip`. If the test runs,
report a skip using :c:func:`ztest_test_skip` or :c:macro:`Z_TEST_SKIP_IFDEF`. If the test runs,
it needs to report either a pass or fail. For example::
#ifdef CONFIG_TEST1
void test_test1(void)
#ifdef CONFIG_TEST1
ZTEST(common, test_test1)
{
zassert_true(1, "true");
zassert_true(1, "true");
}
#else
void test_test1(void)
ZTEST(common, test_test1)
{
ztest_test_skip();
}
#endif
ZTEST(common, test_test2)
{
Z_TEST_SKIP_IFDEF(CONFIG_BUGxxxxx);
zassert_equal(1, 0, NULL);
}
void test_main(void)
{
ztest_test_suite(common,
ztest_unit_test(test_test1),
ztest_unit_test(test_test2)
);
ztest_run_test_suite(common);
}
Use the following macro at the start of your test to skip it with a KConfig
option.
#define Z_TEST_SKIP_IFDEF(config)
For example::
void test_test1(void)
{
Z_TEST_SKIP_IFDEF(CONFIG_BUGxxxxx);
zassert_equal(1, 0, NULL);
}
ZTEST_SUITE(common, NULL, NULL, NULL, NULL, NULL);
Quick start - Unit testing
**************************
@ -169,8 +315,6 @@ and are used to decide whether a test failed or passed by verifying whether an
interaction with an object occurred, and if required, to assert the order of
that interaction.
.. _main_c_bp:
Best practices for declaring the test suite
===========================================
@ -189,193 +333,6 @@ subcases that a Zephyr *ztest* test image will expose.
high-level test project level, particularly when tests do too
many things, is too vague.
There exist two alternatives to writing tests. The first, and more verbose,
approach is to directly declare and run the test suites.
Here is a generic template for a test showing the expected use of
:c:func:`ztest_test_suite`:
.. code-block:: C
#include <zephyr/ztest.h>
extern void test_sometest1(void);
extern void test_sometest2(void);
#ifndef CONFIG_WHATEVER /* Conditionally skip test_sometest3 */
void test_sometest3(void)
{
ztest_test_skip();
}
#else
extern void test_sometest3(void);
#endif
extern void test_sometest4(void);
...
void test_main(void)
{
ztest_test_suite(common,
ztest_unit_test(test_sometest1),
ztest_unit_test(test_sometest2),
ztest_unit_test(test_sometest3),
ztest_unit_test(test_sometest4)
);
ztest_run_test_suite(common);
}
Alternatively, it is possible to split tests across multiple files using
:c:func:`ztest_register_test_suite` which bypasses the need for ``extern``:
.. code-block:: C
#include <zephyr/ztest.h>
void test_sometest1(void) {
zassert_true(1, "true");
}
ztest_register_test_suite(common, NULL,
ztest_unit_test(test_sometest1)
);
The above sample simple registers the test suite and uses a ``NULL`` pragma
function (more on that later). It is important to note that the test suite isn't
directly run in this file. Instead two alternatives exist for running the suite.
First, if to do nothing. A default ``test_main`` function is provided by
ztest. This is the preferred approach if the test doesn't involve a state and
doesn't require use of the pragma.
In cases of an integration test it is possible that some general state needs to
be set between test suites. This can be thought of as a state diagram in which
``test_main`` simply goes through various actions that modify the board's
state and different test suites need to run. This is achieved in the following:
.. code-block:: C
#include <zephyr/ztest.h>
struct state {
bool is_hibernating;
bool is_usb_connected;
}
static bool pragma_always(const void *state)
{
return true;
}
static bool pragma_not_hibernating_not_connected(const void *s)
{
struct state *state = s;
return !state->is_hibernating && !state->is_usb_connected;
}
static bool pragma_usb_connected(const void *s)
{
return ((struct state *)s)->is_usb_connected;
}
ztest_register_test_suite(baseline, pragma_always,
ztest_unit_test(test_case0));
ztest_register_test_suite(before_usb, pragma_not_hibernating_not_connected,
ztest_unit_test(test_case1),
ztest_unit_test(test_case2));
ztest_register_test_suite(with_usb, pragma_usb_connected,,
ztest_unit_test(test_case3),
ztest_unit_test(test_case4));
void test_main(void)
{
struct state state;
/* Should run `baseline` test suite only. */
ztest_run_registered_test_suites(&state);
/* Simulate power on and update state. */
emulate_power_on();
/* Should run `baseline` and `before_usb` test suites. */
ztest_run_registered_test_suites(&state);
/* Simulate plugging in a USB device. */
emulate_plugging_in_usb();
/* Should run `baseline` and `with_usb` test suites. */
ztest_run_registered_test_suites(&state);
/* Verify that all the registered test suites actually ran. */
ztest_verify_all_registered_test_suites_ran();
}
For *twister* to parse source files and create a list of subcases,
the declarations of :c:func:`ztest_test_suite` and
:c:func:`ztest_register_test_suite` must follow a few rules:
- one declaration per line
- conditional execution by using :c:func:`ztest_test_skip`
What to avoid:
- packing multiple testcases in one source file
.. code-block:: C
void test_main(void)
{
#ifdef TEST_feature1
ztest_test_suite(feature1,
ztest_unit_test(test_1a),
ztest_unit_test(test_1b),
ztest_unit_test(test_1c)
);
ztest_run_test_suite(feature1);
#endif
#ifdef TEST_feature2
ztest_test_suite(feature2,
ztest_unit_test(test_2a),
ztest_unit_test(test_2b)
);
ztest_run_test_suite(feature2);
#endif
}
- Do not use ``#if``
.. code-block:: C
ztest_test_suite(common,
ztest_unit_test(test_sometest1),
ztest_unit_test(test_sometest2),
#ifdef CONFIG_WHATEVER
ztest_unit_test(test_sometest3),
#endif
ztest_unit_test(test_sometest4),
...
- Do not add comments on lines with a call to :c:func:`ztest_unit_test`:
.. code-block:: C
ztest_test_suite(common,
ztest_unit_test(test_sometest1),
ztest_unit_test(test_sometest2) /* will fail */,
/* will fail! */ ztest_unit_test(test_sometest3),
ztest_unit_test(test_sometest4),
...
- Do not define multiple definitions of unit / user unit test case per
line
.. code-block:: C
ztest_test_suite(common,
ztest_unit_test(test_sometest1), ztest_unit_test(test_sometest2),
ztest_unit_test(test_sometest3),
ztest_unit_test(test_sometest4),
...
Other questions:
- Why not pre-scan with CPP and then parse? or post scan the ELF file?
@ -492,24 +449,17 @@ Example output for a failed macro from
.. doxygengroup:: ztest_assume
Mocking
=======
These functions allow abstracting callbacks and related functions and
controlling them from specific tests. You can enable the mocking framework by
setting :kconfig:option:`CONFIG_ZTEST_MOCKING` to "y" in the configuration file of the
test. The amount of concurrent return values and expected parameters is
limited by :kconfig:option:`CONFIG_ZTEST_PARAMETER_COUNT`.
.. _mocking-fff:
Here is an example for configuring the function ``expect_two_parameters`` to
expect the values ``a=2`` and ``b=3``, and telling ``returns_int`` to return
``5``:
Mocking via FFF
===============
.. literalinclude:: mocking.c
:language: c
:linenos:
Zephyr has integrated with FFF for mocking. See `FFF`_ for documentation. To use it, use the
following in your source::
#include <zephyr/fff.h>
.. doxygengroup:: ztest_mock
Customizing Test Output
***********************
@ -558,3 +508,5 @@ For example
$ zephyr.exe -list
$ zephyr.exe -test="fixture_tests::test_fixture_pointer,framework_tests::test_assert_mem_equal"
$ zephyr.exe -test="framework_tests::*"
.. _FFF: https://github.com/meekrosoft/fff

View file

@ -0,0 +1,266 @@
.. _test-framework-deprecated:
ZTest Deprecated APIs
#####################
Ztest is currently being migrated to a new API, this documentation provides information about the
deprecated APIs which will eventually be removed. See :ref:`Test Framework <test-framework>` for the new API.
Similarly, ZTest's mocking framework is also deprecated (see :ref:`Mocking via FFF <mocking-fff>`).
Quick start - Unit testing
**************************
Ztest can be used for unit testing. This means that rather than including the
entire Zephyr OS for testing a single function, you can focus the testing
efforts into the specific module in question. This will speed up testing since
only the module will have to be compiled in, and the tested functions will be
called directly.
Since you won't be including basic kernel data structures that most code
depends on, you have to provide function stubs in the test. Ztest provides
some helpers for mocking functions, as demonstrated below.
In a unit test, mock objects can simulate the behavior of complex real objects
and are used to decide whether a test failed or passed by verifying whether an
interaction with an object occurred, and if required, to assert the order of
that interaction.
.. _main_c_bp:
Best practices for declaring the test suite
===========================================
*twister* and other validation tools need to obtain the list of
subcases that a Zephyr *ztest* test image will expose.
.. admonition:: Rationale
This all is for the purpose of traceability. It's not enough to
have only a semaphore test project. We also need to show that we
have testpoints for all APIs and functionality, and we trace back
to documentation of the API, and functional requirements.
The idea is that test reports show results for every sub-testcase
as passed, failed, blocked, or skipped. Reporting on only the
high-level test project level, particularly when tests do too
many things, is too vague.
There exist two alternatives to writing tests. The first, and more verbose,
approach is to directly declare and run the test suites.
Here is a generic template for a test showing the expected use of
:c:func:`ztest_test_suite`:
.. code-block:: C
#include <zephyr/ztest.h>
extern void test_sometest1(void);
extern void test_sometest2(void);
#ifndef CONFIG_WHATEVER /* Conditionally skip test_sometest3 */
void test_sometest3(void)
{
ztest_test_skip();
}
#else
extern void test_sometest3(void);
#endif
extern void test_sometest4(void);
...
void test_main(void)
{
ztest_test_suite(common,
ztest_unit_test(test_sometest1),
ztest_unit_test(test_sometest2),
ztest_unit_test(test_sometest3),
ztest_unit_test(test_sometest4)
);
ztest_run_test_suite(common);
}
Alternatively, it is possible to split tests across multiple files using
:c:func:`ztest_register_test_suite` which bypasses the need for ``extern``:
.. code-block:: C
#include <zephyr/ztest.h>
void test_sometest1(void) {
zassert_true(1, "true");
}
ztest_register_test_suite(common, NULL,
ztest_unit_test(test_sometest1)
);
The above sample simple registers the test suite and uses a ``NULL`` pragma
function (more on that later). It is important to note that the test suite isn't
directly run in this file. Instead two alternatives exist for running the suite.
First, if to do nothing. A default ``test_main`` function is provided by
ztest. This is the preferred approach if the test doesn't involve a state and
doesn't require use of the pragma.
In cases of an integration test it is possible that some general state needs to
be set between test suites. This can be thought of as a state diagram in which
``test_main`` simply goes through various actions that modify the board's
state and different test suites need to run. This is achieved in the following:
.. code-block:: C
#include <zephyr/ztest.h>
struct state {
bool is_hibernating;
bool is_usb_connected;
}
static bool pragma_always(const void *state)
{
return true;
}
static bool pragma_not_hibernating_not_connected(const void *s)
{
struct state *state = s;
return !state->is_hibernating && !state->is_usb_connected;
}
static bool pragma_usb_connected(const void *s)
{
return ((struct state *)s)->is_usb_connected;
}
ztest_register_test_suite(baseline, pragma_always,
ztest_unit_test(test_case0));
ztest_register_test_suite(before_usb, pragma_not_hibernating_not_connected,
ztest_unit_test(test_case1),
ztest_unit_test(test_case2));
ztest_register_test_suite(with_usb, pragma_usb_connected,,
ztest_unit_test(test_case3),
ztest_unit_test(test_case4));
void test_main(void)
{
struct state state;
/* Should run `baseline` test suite only. */
ztest_run_registered_test_suites(&state);
/* Simulate power on and update state. */
emulate_power_on();
/* Should run `baseline` and `before_usb` test suites. */
ztest_run_registered_test_suites(&state);
/* Simulate plugging in a USB device. */
emulate_plugging_in_usb();
/* Should run `baseline` and `with_usb` test suites. */
ztest_run_registered_test_suites(&state);
/* Verify that all the registered test suites actually ran. */
ztest_verify_all_registered_test_suites_ran();
}
For *twister* to parse source files and create a list of subcases,
the declarations of :c:func:`ztest_test_suite` and
:c:func:`ztest_register_test_suite` must follow a few rules:
- one declaration per line
- conditional execution by using :c:func:`ztest_test_skip`
What to avoid:
- packing multiple testcases in one source file
.. code-block:: C
void test_main(void)
{
#ifdef TEST_feature1
ztest_test_suite(feature1,
ztest_unit_test(test_1a),
ztest_unit_test(test_1b),
ztest_unit_test(test_1c)
);
ztest_run_test_suite(feature1);
#endif
#ifdef TEST_feature2
ztest_test_suite(feature2,
ztest_unit_test(test_2a),
ztest_unit_test(test_2b)
);
ztest_run_test_suite(feature2);
#endif
}
- Do not use ``#if``
.. code-block:: C
ztest_test_suite(common,
ztest_unit_test(test_sometest1),
ztest_unit_test(test_sometest2),
#ifdef CONFIG_WHATEVER
ztest_unit_test(test_sometest3),
#endif
ztest_unit_test(test_sometest4),
...
- Do not add comments on lines with a call to :c:func:`ztest_unit_test`:
.. code-block:: C
ztest_test_suite(common,
ztest_unit_test(test_sometest1),
ztest_unit_test(test_sometest2) /* will fail */,
/* will fail! */ ztest_unit_test(test_sometest3),
ztest_unit_test(test_sometest4),
...
- Do not define multiple definitions of unit / user unit test case per
line
.. code-block:: C
ztest_test_suite(common,
ztest_unit_test(test_sometest1), ztest_unit_test(test_sometest2),
ztest_unit_test(test_sometest3),
ztest_unit_test(test_sometest4),
...
Other questions:
- Why not pre-scan with CPP and then parse? or post scan the ELF file?
If C pre-processing or building fails because of any issue, then we
won't be able to tell the subcases.
- Why not declare them in the YAML testcase description?
A separate testcase description file would be harder to maintain
than just keeping the information in the test source files
themselves -- only one file to update when changes are made
eliminates duplication.
Mocking
*******
These functions allow abstracting callbacks and related functions and
controlling them from specific tests. You can enable the mocking framework by
setting :kconfig:option:`CONFIG_ZTEST_MOCKING` to "y" in the configuration file of the
test. The amount of concurrent return values and expected parameters is
limited by :kconfig:option:`CONFIG_ZTEST_PARAMETER_COUNT`.
Here is an example for configuring the function ``expect_two_parameters`` to
expect the values ``a=2`` and ``b=3``, and telling ``returns_int`` to return
``5``:
.. literalinclude:: mocking.c
:language: c
:linenos:
.. doxygengroup:: ztest_mock

View file

@ -50,6 +50,43 @@ struct ztest_suite_stats {
uint32_t fail_count;
};
/**
* Setup function to run before running this suite
*
* @return Pointer to the data structure that will be used throughout this test suite
*/
typedef void *(*ztest_suite_setup_t)(void);
/**
* Function to run before each test in this suite
*
* @param fixture The test suite's fixture returned from setup()
*/
typedef void (*ztest_suite_before_t)(void *fixture);
/**
* Function to run after each test in this suite
*
* @param fixture The test suite's fixture returned from setup()
*/
typedef void (*ztest_suite_after_t)(void *fixture);
/**
* Teardown function to run after running this suite
*
* @param fixture The test suite's data returned from setup()
*/
typedef void (*ztest_suite_teardown_t)(void *fixture);
/**
* An optional predicate function to determine if the test should run. If NULL, then the
* test will only run once on the first attempt.
*
* @param global_state The current state of the test application.
* @return True if the suite should be run; false to skip.
*/
typedef bool (*ztest_suite_predicate_t)(const void *global_state);
/**
* A single node of test suite. Each node should be added to a single linker section which will
* allow ztest_run_test_suites() to iterate over the various nodes.
@ -57,38 +94,22 @@ struct ztest_suite_stats {
struct ztest_suite_node {
/** The name of the test suite. */
const char *const name;
/**
* Setup function to run before running this suite
*
* @return Pointer to the data structure that will be used throughout this test suite
*/
void *(*const setup)(void);
/**
* Function to run before each test in this suite
*
* @param data The test suite's data returned from setup()
*/
void (*const before)(void *data);
/**
* Function to run after each test in this suite
*
* @param data The test suite's data returned from setup()
*/
void (*const after)(void *data);
/**
* Teardown function to run after running this suite
*
* @param data The test suite's data returned from setup()
*/
void (*const teardown)(void *data);
/**
* An optional predicate function to determine if the test should run. If NULL, then the
* test will only run once on the first attempt.
*
* @param state The current state of the test application.
* @return True if the suite should be run; false to skip.
*/
bool (*const predicate)(const void *state);
/** Setup function */
const ztest_suite_setup_t setup;
/** Before function */
const ztest_suite_before_t before;
/** After function */
const ztest_suite_after_t after;
/** Teardown function */
const ztest_suite_teardown_t teardown;
/** Optional predicate filter */
const ztest_suite_predicate_t predicate;
/** Stats */
struct ztest_suite_stats *const stats;
};
@ -131,7 +152,7 @@ extern struct ztest_suite_node _ztest_suite_node_list_end[];
void ztest_run_all(const void *state);
/**
* Run the registered unit tests which return true from their pragma function.
* Run the registered unit tests which return true from their predicate function.
*
* @param state The current state of the machine as it relates to the test executable.
* @return The number of tests that ran.
@ -181,6 +202,18 @@ int z_ztest_run_test_suite(const char *name);
*/
struct ztest_unit_test *z_ztest_get_next_test(const char *suite, struct ztest_unit_test *prev);
/* definitions for use with testing application shared memory */
#ifdef CONFIG_USERSPACE
#define ZTEST_DMEM K_APP_DMEM(ztest_mem_partition)
#define ZTEST_BMEM K_APP_BMEM(ztest_mem_partition)
#define ZTEST_SECTION K_APP_DMEM_SECTION(ztest_mem_partition)
extern struct k_mem_partition ztest_mem_partition;
#else
#define ZTEST_DMEM
#define ZTEST_BMEM
#define ZTEST_SECTION .data
#endif
/**
* @defgroup ztest_test Ztest testing macros
* @ingroup ztest
@ -215,17 +248,6 @@ void ztest_test_pass(void);
*/
void ztest_test_skip(void);
/**
* @brief Do nothing, successfully.
*
* Unit test / setup function / teardown function that does
* nothing, successfully. Can be used as a parameter to
* ztest_unit_test_setup_teardown().
*/
static inline void unit_test_noop(void)
{
}
#define Z_TEST(suite, fn, t_options, use_fixture) \
static void _##suite##_##fn##_wrapper(void *data); \
static void suite##_##fn( \
@ -323,6 +345,7 @@ static inline void unit_test_noop(void)
*/
typedef void (*ztest_rule_cb)(const struct ztest_unit_test *test, void *data);
/** @private */
struct ztest_test_rule {
ztest_rule_cb before_each;
ztest_rule_cb after_each;
@ -343,8 +366,9 @@ struct ztest_test_rule {
* - Test rule's `after` function is not guaranteed to run in any particular order.
*
* @param name The name for the test rule (must be unique within the compilation unit)
* @param before_each_fn The callback function to call before each test (may be NULL)
* @param after_each_fn The callback function to call after each test (may be NULL)
* @param before_each_fn The callback function (ztest_rule_cb) to call before each test
* (may be NULL)
* @param after_each_fn The callback function (ztest_rule_cb) to call after each test (may be NULL)
*/
#define ZTEST_RULE(name, before_each_fn, after_each_fn) \
static STRUCT_SECTION_ITERABLE(ztest_test_rule, z_ztest_test_rule_##name) = { \
@ -373,18 +397,6 @@ void ztest_simple_1cpu_before(void *data);
*/
void ztest_simple_1cpu_after(void *data);
/* definitions for use with testing application shared memory */
#ifdef CONFIG_USERSPACE
#define ZTEST_DMEM K_APP_DMEM(ztest_mem_partition)
#define ZTEST_BMEM K_APP_BMEM(ztest_mem_partition)
#define ZTEST_SECTION K_APP_DMEM_SECTION(ztest_mem_partition)
extern struct k_mem_partition ztest_mem_partition;
#else
#define ZTEST_DMEM
#define ZTEST_BMEM
#define ZTEST_SECTION .data
#endif
/**
* @brief Run the specified test suite.
*