Zephyrのテストフレームワーク調査②〜はじめてのZtest〜
はじめに
Zephyrにはテストフレームワーク (Mockもあります!) が用意されています。 テストは大事です。さっさとテストを作れるようにしましょう!
何事も写経から、ということで、サンプルの写経を行っていきます。
汎用テンプレート
まずは、公式にあるテンプレートを眺めます。
#include <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); }
このソースコードは、sanitycheckスクリプトが解析するため、ztest_test_suite
の宣言は、以下のルールに従う必要があります。
- 1行1宣言
- 条件実行は、
ztest_test_skip()
を使用
ztest_test_suite
の中にifdef
マクロがあったり、1行で2つ以上のテストケースは書けません。
CMakeLists.txt
まずは、cmakeを写経します。
cmake_minimum_required(VERSION 3.8.2) if(BOARD STREQUAL unit_testing) list(APPEND SOURCES src/main.c) include($ENV{ZEPHYR_BASE}/tests/unit/unittest.cmake) project(base) else() include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE) project(base) FILE(GLOB app_sources src/*.c) target_sources(app PRIVATE ${app_sources}) endif()
ん?BOARDがunit_testing
かどうかで処理が分岐していますね。
試しにサンプルに戻って、-DBOARD=unit_testing
で実験してみます。
# at zephyr/tests/ztest/test/base/ $ mkdir build && cd $_ $ cmake -GNinja -DBOARD=unit_testing .. $ ninja [5/5] Linking C executable testbinary
む、何やらtestbinary
なるバイナリが出てきました。
$ ./testbinary Running test suite framework_tests =================================================================== starting test - test_empty_test PASS - test_empty_test =================================================================== starting test - test_assert_tests PASS - test_assert_tests =================================================================== Test suite framework_tests succeeded =================================================================== PROJECT EXECUTION SUCCESSFUL
いけるやん!
build.ninja
を確認すると、run-test
というコマンドがあります。
$ ninja run-test Running test suite framework_tests =================================================================== starting test - test_empty_test PASS - test_empty_test =================================================================== starting test - test_assert_tests PASS - test_assert_tests =================================================================== Test suite framework_tests succeeded =================================================================== PROJECT EXECUTION SUCCESSFUL
いけるやん!
特定のユニットテストだけの実行であれば、高速にテストできます。
testcase.yaml
特に言うことはないですね。
tests: testing.ztest: tags: test_practice type: unit testing.ztest.verbose_0: extra_args: CONF_FILE=prj_verbose_0.conf tags: test_practice
prj.conf
最低限、CONFIG_ZTEST
が必要です。
CONFIG_ZTEST=y
src/main.c
ありきたりなテストを書いてみます。
#include <ztest.h> static void my_first_test(void) { zassert_true(1, NULL); } void test_main(void) { ztest_test_suite(my_first_tests, ztest_unit_test(my_first_test) ); ztest_run_test_suite(my_first_tests); }
zassert_true()
のAPI仕様は次のとおりです。
zassert_true(cond, msg, ...) Assert that cond is true. Parameters cond: Condition to check msg: Optional message to print if the assertion fails
オプショナルなメッセージが不要な場合は、NULLにするようです(こういうの好きではないですが)。
次は、Mockを試してみたいと思います。