Testing
Creating a test suite
ZTEST_SUITE
/**
* Create and register a ztest suite. Using this macro creates a new test suite (using
* ztest_test_suite). It then creates a struct ztest_suite_node in a specific linker section.
*
* Tests can then be run by calling ztest_run_test_suites(const void *state) by passing
* in the current state. See the documentation for ztest_run_test_suites for more info.
*
* @param SUITE_NAME The name of the suite (see ztest_test_suite for more info)
* @param PREDICATE A function to test against the state and determine if the test should run.
* @param setup_fn The setup function to call before running this test suite
* @param before_fn The function to call before each unit test in this suite
* @param after_fn The function to call after each unit test in this suite
* @param teardown_fn The function to call after running all the tests in this suite
**/
#define ZTEST_SUITE(SUITE_NAME, PREDICATE, setup_fn, before_fn, after_fn, teardown_fn) \
struct ztest_suite_stats UTIL_CAT(z_ztest_suite_node_stats_, SUITE_NAME); \
static const STRUCT_SECTION_ITERABLE(ztest_suite_node, \
UTIL_CAT(z_ztest_test_node_, SUITE_NAME)) = { \
.name = STRINGIFY(SUITE_NAME), \
.setup = (setup_fn), \
.before = (before_fn), \
.after = (after_fn), \
.teardown = (teardown_fn), \
.predicate = PREDICATE, \
.stats = &UTIL_CAT(z_ztest_suite_node_stats_, SUITE_NAME), \
}
.setup
: 每个test suite run都会调用一次。.before
: 每个single test in the test suite run前都会调用一次。.after
: 每个single test in the test suite run后都会调用一次。.teardown
: 所有tests跑完后会调用一次。.predicate
: return bool类型的函数,可以在里面判断全局变量状态,来决定是否要进行test。
Adding tests to a suite
ZTEST(suite_name, test_name)
: suite_name为上面通过ZTEST_SUITE创建的SUITE_NAME, test_name为测试名称。ZTEST_USER(suite_name, test_name)
: 和ZTEST类似,不过在CONFIG_USERSPACE
打开后,测试会跑在userspace线程。ZTEST_F(suite_name, test_name)
: 和ZTEST类似,不过会自带一个类型为<suite_name>_fixture
的fixture
变量。ZTEST_USER_F
:结合2,3两条。
Quick start - Integration testing 集成测试
./scripts/twister -s tests/foo/bar/test-identifier
运行定义在testcase.yaml
中的test-identifier。
./scripts/twister -T tests/foo/bar/
运行所有foo/bar/目录下的测试。
几条规则:
- 定义的测试名需要有
test_
前缀。 - 测试需要用doxygen说明。
- 测试名不能重复。
e.g.
/**
* @brief Test Asserts
*
* This test verifies the zassert_true macro.
*/
ZTEST(my_suite, test_assert)
{
zassert_true(1, "1 was false");
}
Listing Tests
twister --list-tests -T tests/kernel
: 列出tests/kernel
下的所有测试。
Skipping Tests
利用 ztest_test_skip() or Z_TEST_SKIP_IFDEF
#ifdef CONFIG_TEST1
ZTEST(common, test_test1)
{
zassert_true(1, "true");
}
#else
ZTEST(common, test_test1)
{
ztest_test_skip();
}
#endif
ZTEST(common, test_test2)
{
Z_TEST_SKIP_IFDEF(CONFIG_BUGxxxxx);
zassert_equal(1, 0, NULL);
}
Quick start - Unit testing 单元测试
examples:tests/unit
CMakeLists需要指明unit test:
cmake_minimum_required(VERSION 3.20.0)
project(app)
find_package(Zephyr COMPONENTS unittest REQUIRED HINTS $ENV{ZEPHYR_BASE})
target_sources(testbinary PRIVATE main.c)
Stress test framework
//TODO: