测试风格和命名¶
为了使查找、编写和使用KUnit测试尽可能简单,强烈建议按照以下准则命名和编写它们。虽然可以编写不遵循这些规则的KUnit测试,但它们可能会破坏某些工具,可能会与其他测试冲突,并且可能不会被测试系统自动运行。
建议仅在以下情况下偏离这些准则
将已知名称的测试移植到KUnit。
编写如果自动运行会导致严重问题的测试。 例如,非确定性地产生误报或误报,或者花费很长时间才能运行。
子系统、套件和测试¶
为了使测试易于查找,它们被分组到套件和子系统中。 测试套件是测试内核相关区域的一组测试。 子系统是一组测试套件,用于测试内核子系统或驱动程序的各个部分。
子系统¶
每个测试套件必须属于一个子系统。 子系统是一个或多个KUnit测试套件的集合,用于测试同一驱动程序或内核的一部分。 测试子系统应匹配单个内核模块。 如果被测试的代码无法编译为模块,在许多情况下,子系统应对应于源树中的目录或MAINTAINERS
文件中的条目。 如果不确定,请遵循类似区域中的测试设置的约定。
测试子系统应以被测试的代码命名,要么以模块命名(如果可能),要么以被测试的目录或文件命名。 应命名测试子系统以避免必要的歧义。
如果测试子系统名称有多个组件,则应以下划线分隔。 请勿直接在子系统名称中包含“test”或“kunit”,除非我们实际上正在测试其他测试或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>是测试套件的名称。与被测驱动程序/子系统的配置条目一起列出,或在[内核Hacking]->[内核测试和覆盖率]下
依赖于
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”是核心模块,则“foobar_kunit”是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
文件中。