测试风格和命名¶
为了使查找、编写和使用 KUnit 测试尽可能简单,强烈建议按照以下准则对其进行命名和编写。 虽然可以编写不遵循这些规则的 KUnit 测试,但它们可能会破坏某些工具,可能与其他测试冲突,并且可能不会被测试系统自动运行。
建议您仅在以下情况下偏离这些准则
将已知名称的测试移植到 KUnit。
编写如果自动运行会导致严重问题的测试。 例如,非确定性地产生误报或误报,或者运行时间很长。
子系统、套件和测试¶
为了使测试易于查找,它们被分组到套件和子系统中。 测试套件是一组测试内核相关区域的测试。 子系统是一组测试内核子系统或驱动程序不同部分的测试套件。
子系统¶
每个测试套件都必须属于一个子系统。 子系统是一个或多个 KUnit 测试套件的集合,这些测试套件测试相同的驱动程序或内核的一部分。 测试子系统应与单个内核模块匹配。 如果要测试的代码无法编译为模块,在许多情况下,子系统应对应于源代码树中的目录或 MAINTAINERS
文件中的条目。 如果不确定,请遵循类似区域中测试设置的约定。
测试子系统应以正在测试的代码命名,要么以模块命名(如果可能),要么以正在测试的目录或文件命名。 测试子系统应进行命名,以避免在必要时产生歧义。
如果测试子系统名称有多个组成部分,则应使用下划线分隔。 除非我们实际上正在测试其他测试或 kunit 框架本身,否则不要在子系统名称中直接包含“test”或“kunit”。 例如,子系统可以称为
ext4
匹配模块和文件系统名称。
apparmor
匹配模块名称和 LSM 名称。
kasan
该工具的常用名称,路径的突出部分
mm/kasan
snd_hda_codec_hdmi
具有多个组成部分(
snd
、hda
、codec
、hdmi
),用下划线分隔。 匹配模块名称。
避免使用以下示例中所示的名称
linear-ranges
名称应使用下划线而不是破折号分隔单词。 首选
linear_ranges
。qos-kunit-test
此名称应使用下划线,并且不应将“kunit-test”作为后缀。
qos
作为子系统名称也是不明确的,因为内核的多个部分都有一个qos
子系统。power_qos
会是一个更好的名字。pc_parallel_port
相应的模块名称是
parport_pc
,因此此子系统也应命名为parport_pc
。
注意
KUnit API 和工具不明确了解子系统。 它们是一种对测试套件进行分类和命名模块的方式,为人们提供了一种简单、一致的方式来查找和运行测试。 这可能会在未来发生变化。
套件¶
KUnit 测试分组到测试套件中,这些套件涵盖正在测试的特定功能区域。 测试套件可以具有共享的初始化和关闭代码,这些代码在套件中的所有测试中运行。 并非所有子系统都需要拆分为多个测试套件(例如,简单的驱动程序)。
测试套件以它们所属的子系统命名。 如果子系统包含多个套件,则应将正在测试的特定区域附加到子系统名称,并用下划线分隔。
如果子系统内使用 KUnit 进行多种类型的测试(例如,单元测试和集成测试),则应将它们放入单独的套件中,并将测试类型作为套件名称中的最后一个元素。 除非这些测试实际存在,否则请避免在套件名称中使用 _test
、_unittest
或类似内容。
完整的测试套件名称(包括子系统名称)应指定为 kunit_suite
结构体的 .name
成员,并构成模块名称的基础。 例如,测试套件可能包括
ext4_inode
ext4
子系统的一部分,测试inode
区域。kunit_try_catch
kunit
实现本身的一部分,测试try_catch
区域。apparmor_property_entry
apparmor
子系统的一部分,测试property_entry
区域。kasan
kasan
子系统只有一个套件,因此套件名称与子系统名称相同。
避免使用名称,例如
ext4_ext4_inode
没有理由两次声明子系统。
property_entry
如果没有子系统名称,则套件名称是不明确的。
kasan_integration_test
因为
kasan
子系统中只有一个套件,因此该套件应仅称为kasan
。 不要冗余地添加integration_test
。 它应该是一个单独的测试套件。 例如,如果添加单元测试,则该套件可以命名为kasan_unittest
或类似名称。
测试用例¶
单个测试由一个测试约束代码路径、属性或函数的函数组成。 在测试输出中,单个测试的结果将显示为套件结果的子测试。
测试应以它们正在测试的内容命名。 这通常是被测函数的名称,并带有对正在测试的输入或代码路径的描述。 由于测试是 C 函数,因此应按照内核编码风格对其进行命名和编写。
注意
由于测试本身是函数,因此它们的名称不能与内核中的其他 C 标识符冲突。 这可能需要一些创造性的命名。 最好使您的测试函数为 static,以避免污染全局命名空间。
示例测试名称包括
unpack_u32_with_null_name
当传入 NULL 名称时测试
unpack_u32
函数。test_list_splice
测试
list_splice
宏。 它具有前缀test_
以避免与宏本身发生名称冲突。
如果需要在其测试套件的上下文之外引用测试,则测试的完全限定名称应为套件名称后跟测试名称,并用冒号分隔(即 suite:test
)。
测试 Kconfig 条目¶
每个测试套件都应绑定到一个 Kconfig 条目。
此 Kconfig 条目必须
命名为
CONFIG_<name>_KUNIT_TEST
:其中 <name> 是测试套件的名称。列在正在测试的驱动程序/子系统的配置条目旁边,或位于 [内核黑客] -> [内核测试和覆盖率] 下。
依赖于
CONFIG_KUNIT
。仅在未启用
CONFIG_KUNIT_ALL_TESTS
时可见。默认值为
CONFIG_KUNIT_ALL_TESTS
。在帮助文本中简要描述 KUnit。
如果我们无法满足上述条件(例如,测试无法构建为模块),则测试的 Kconfig 条目应为三态。
例如,Kconfig 条目可能如下所示
config FOO_KUNIT_TEST
tristate "KUnit test for foo" if !KUNIT_ALL_TESTS
depends on KUNIT
default KUNIT_ALL_TESTS
help
This builds unit tests for foo.
For more information on KUnit and unit tests in general,
please refer to the KUnit documentation in Documentation/dev-tools/kunit/.
If unsure, say N.
测试文件和模块名称¶
KUnit 测试通常被编译成单独的模块。为了避免与常规模块冲突,KUnit 模块应该以测试套件的名称命名,后跟 _kunit
(例如,如果核心模块是“foobar”,那么 KUnit 测试模块就是“foobar_kunit”)。
测试源文件,无论是编译成单独的模块还是在另一个源文件中 #include
,最好都放在 tests/
子目录中,以避免与其他源文件冲突(例如,用于制表符补全)。
请注意,_test
后缀也在一些现有的测试中使用。 建议使用 _kunit
后缀,因为它能更清晰地区分 KUnit 测试和非 KUnit 测试。
因此,对于常见的情况,将包含测试套件的文件命名为 tests/<suite>_kunit.c
。tests
目录应该与被测试的代码位于同一级别。 例如,lib/string.c
的测试位于 lib/tests/string_kunit.c
中。
如果套件名称包含测试父目录的部分或全部名称,则修改源文件名以减少冗余可能是合理的。 例如,一个 foo_firmware
套件可能位于 foo/tests/firmware_kunit.c
文件中。