快速回忆
- 定义suite,上面挂cases
- 定义case函数
- 执行suite
- suite通过结构化初始化把suite和cases当做一个整体
void my_case1_func(struct kunit * test)
struct kunit_case my_test_cases[] = {
KUNIT_CASE(my_case1_func),
}
struct kunit_suite my_test_suite = {
.name = "my test suite",
.test_cases = my_test_cases
}
kunit_run_tests(my_test_suite);
Suite 测试集合,组织起多个cases的(struct kunit_suite)
- 定义test suite,是一个测试集合但是不是直接testcase的函数集合,而是一个suite
- 那么对于suite,假设你是设计者,除了有多个cases,还需要有一个名字方便收集汇总
- 所以test suite定义出一个struct,就有成员name和test_cases。
- 那么更高级的,对于每个suite执行的开始和结束,可以定义函数处理,所以需要suite_init成员
- 同样的每个case执行的开始和结束,所以有了init和exit
struct kunit_suite {
name[256];
struct kunit_case *test_cases;
suite_init(struct kunit_suite *);
suite_exit(struct kunit_suite *);
init(struct kunit *);
exit(struct kunit *);
}
实操:
struct kunit_suite my_test_suite = {
.name = "my test suite",
.test_cases = my_test_cases
}
Cases(struct kunit_case)
- 定义test cases,肯定是一个集合,suite前面有一个* kunit_case,可以是一个数组
- 那么对于cases,假设你是设计者,除了有name,还有func。那么这里func内部就叫run_case,运行的时候直接调用他
- 同样除了有func,还有运行状态要记录到某个case中,就有status
struct kunit_case {
*name;
run_case(struct kunit *);
}
实操:
void my_case1_func(struct kunit * test)
{
//xxx
}
# 一般使用柔性数组定义
struct kunit_case my_test_cases[] = {
{.name = "xxx", .run_case = my_case1_func},
}
# 另外还有一个更快速的结构化定义方法
struct kunit_case my_test_cases[] = {
KUNIT_CASE(my_case1_func), //这里定义.name 就是直接#my_case1_func 转化为字符串
KUNIT_CASE(my_case2_func),
}
这里相当于使用了结构化初始化,把所有需要运行的case,放到my_test_cases的数组中。这样suite上就挂上了所有的cases。
并且每个case的入参都是一个struct kunit,而不是struct kunit_case。
这个kunit相当于是一个中间态的结构体,kunit内部每次执行前定义一个临时的kunit,然后进行执行。每次执行后,把结果更新到这个kunit中,并且使用的kunit的判断宏使用这个kunit里面的status根据判断结果存储进去。比如KUNIT_EXPECT_EQ(test, 1, 1),就会把OK的结果存入test的status中。
然后执行完成后,把执行结果test存储到case的status中。
运行
- 如果要运行这个suite,假设是一个设计者,提供一个接口,把suite指定进去,就能通过遍历suite的test_cases数组就能一一的执行所有的case,并且每个case执行结构可以存入每个case的status种。执行完了把所有的状态统计存入suite的status
kunit_run_tests(my_test_suite)
suite -> 找到cases -> 然后一一的运行case并且存入状态 -> 运行完成
模板
void my_case1_func(struct kunit * test)
{
//xxx
}
struct kunit_case my_test_cases[] = {
KUNIT_CASE(my_case1_func), //这里定义.name 就是直接#my_case1_func 转化为字符串
KUNIT_CASE(my_case2_func),
}
struct kunit_suite my_test_suite = {
.name = "my test suite",
.test_cases = my_test_cases
}
# 执行
kunit_run_tests(my_test_suite);
综述
- kunit使用3个对象 suite - case - 临时struct kunit,以及一个主要接口 kunit_run_tests
- 从设计者角度定义多个case叫suite,里面有cases。然后定义某个case包括名字和函数。然后定义执行使用kunit结构存储状态。
- 然后要运行所有的case,就把suite作为一个句柄传进去,kunit_run_tests根据suite遍历cases,并且执行中根据KUNIT宏定义判断更新到临时的kunit的status,执行完成后更新到case的status,最后执行完之后suite根据所有的数据更新到suite的数据中。