ceedling深入探讨(下)

        在上篇文章里面介绍了ceedling的安装和简单的使用,对ceedling框架有了一定的理解。本文将对ceedling进行更多的介绍。

一、ceedling

  1. projetc.yaml

        projetc.yaml是整个工程的配置文件,根据需要对文件内容进行配置。考虑到我们测试代码的时候有时候不方便直接将ceedling框架添加到自己的源码中,因此,可以在projetc.yaml中指定需要包含的文件。

         下面的 – C:\User****就是新添加的文件路径。除此之外还有库路径可以添加等等。我们测试的文件名叫做test_add.c,前缀名字是test_,这个使用的是默认前缀名,也可以修改。

 同理,CMock的前缀也可以修改,默认是mock_,CMock头文件前缀。

:when_no_prototypes: :默认warn,使用CMock对一个头文件创建mock函数时,头文件里面应当包含函数原型。当其中不包含函数原型时,CMock组件怎么做。可设置为warn,ignore,error。

:enforce_strict_ordering: 默认TRUE,用于配置CMock检查函数的调用顺序

:plugins: 用于配置CMokc生成的函数。Xxx_Expect总是默认生成(例如上篇文章中生成的fun_ExpectAndReturn),以下可选,生成对应的函数:

- :ignore
- :ignore_arg
- :expect_any_args
- :array
- :cexception
- :callback
- :return_thru_ptr

备注:添加某个选项时,执行test指令之后,CMock可能无法生成对应的函数,将build目录删了,重新运行即可。

下面的treat_as是支持的数据类型,可以添加,可选的有(图是从官方pdf文档截出来的,清晰的图可以去官方GitHub上,上篇博客给出了链接):

         有时候我们需要对代码覆盖率进行测试,因此需要使用gcov生成代码覆盖率报告,在project.yaml文件中添加该功能,加上- gcov即可,使用时类似test指令。

二、测试

        先将add.c的代码进行修改,修改之后的代码:

test_add.c代码: 

 其中,setUp函数是在测试之前对某些资源初始化的函数,之后才会调用test_add_NeedToImplement测试代码,最后调用tearDown函数释放资源,这里都用不到。先使用test指令测试下代码。

 没问题,之后使用gcov生成代码覆盖报告。

 在最下面的add.c那4行,第一行表示有效代码有9行,包含函数名、代码行,不包括括号占用的行数、注释、空白行。当前运行了77.78%的代码数。第2行表示有四个分支,第3行至少运行一次的分支有50%,第4行表示函数调用。使用ceedling utils:gcov指令,可以生成html格式的代码测试报告,更加详细。 在对应目录下我们打开文件。

 

 打开之后,可以看到这样,点击List of functions,可以看到add函数的分析, 

 点击src\add.c,进去可以看到每行代码调用的次数。

 红色表示调用了的代码,前面的数字表示调用了几次,红色表示代码未调用。

三、CMock补充说明

        前面简单的说明了下什么是CMock以及它能干什么。这里对CMock做一些详细的说明,这些说明是博主自己理解的,若是有误之处,请告知博主。

        CMock会根据函数的声明,自动生成一系列函数,并根据需要将其链接到程序中。使用CMock模拟函数, 可以验证它是否收到你想要的数据,并让它返回你想要的任何数据, 让它在你想要的时候抛出错误。其生成的函数在project\htq\build\test\mocks目录下面,有对应的文件,如图

现在假设声明的函数为int do(int a, int b);

CMock会自动生成一个do()函数,并连接到程序中。除此之外,CMock还会生成一系列函数用于测试。

do_ExpectAndReturn (int a, int b, int cmock_to_return);其中a、b是do()中的输入参数,cmock_to_return是函数返回值。Xxx_Expect(根据有没有返回值增加AndReturn)总是会生成。

do_IgnoreAndReturn(int cmock_to_return)会忽略输入,并给出返回值。在不需要关心特定函数被调用的次数或调用它的实际参数时用到,例如读取寄存器的值,不需要给出寄存器的位置,只需要给出其输出值。若是后续不想忽略,则有do_StopIgnore()。

do_AddCallback()会添加一个回调函数,用于执行一些自定义操作。do_AddCallback告诉模拟函数检查其参数并调用,顺序(基于您设置的任何预期)在调用回调之前。回调函数说明:

int do _CALLBACK(int a, int b, int cmock_num_calls);do()回调函数原型

a、b是输入参数,cmock_num_calls是调用次数,第一次调用返回0,第二次返回1,以此类推。do _CALLBACK的返回值会赋值给调用do()的函数,原先使用do_ExpectAndReturn设置的输出值将不再起作用。

do_Stub告诉模拟函数跳过所有正常检查并直接跳到回调函数。在这种情况下,您将替换正常的模拟调用 使用您自己的自定义Stub函数。

CMock生成的函数可以在project.yaml进行配置,以下可选,生成对应的函数:

- :ignore
- :ignore_arg
- :expect_any_args
- :array
- :cexception
- :callback
- :return_thru_ptr

对add.c进行修改。

 htq_fun_1和htq_fun_2的函数声明如下所示。

int htq_fun_1(int a);

int htq_fun_2(int a, int b);

test_add.c中改动

结果如下图。

         htq_fun_1_ExpectAndReturn(1, 1);是CMock框架模拟出来的函数,其参数为xxx函数的输入和输出,输入为1,输出为1,我们只需要告诉他对应的函数声明即可,在上面的代码中,htq_fun_1函数的声明为:int htq_fun_1(int a);CMock自动生成一系列的辅助函数,均已htq_fun_1_开头,如:htq_fun_1_IgnoreAndReturn、htq_fun_1_StopIgnore、htq_fun_1_ExpectAndReturn、htq_fun_1_AddCallback等。

        在测试代码中调用htq_fun_1时,可能会需要调用多次,每次的函数输入均不一样,如htq_fun_1(1);htq_fun_1(2);htq_fun_1(3);则我们也需要调用三次htq_fun_1_ExpectAndReturn(1, 1)、htq_fun_1_ExpectAndReturn(2, 6)、htq_fun_1_ExpectAndReturn(3, 4),代码需要的三个参数1、2、3都要给出其输入、输出,否则会出现错误(提示期望的输入过少)。1、2、3对应的输出值(1、6、4)根据需要写,输入保证都有就行。强调一点,不是说我只是调用了3次htq_fun_1(1),每次输入都是1,我就只需要写入htq_fun_1_ExpectAndReturn(1, 1)一次就够了,不是这样的,也是给出3次,htq_fun_1_ExpectAndReturn调用次数和htq_fun_1调用次数保持一样。经测试,二者也是保持一一对应的调用关系。

四、总结

        到这里,ceedling相关的东西基本介绍的够平常使用的了,想详细了解还请移步作者的github及其网站。以后,若是有机会再来更新ceedling相关的吧。这里放一个国外大佬使用ceedling实战的链接:https://mp.csdn.net/mp_blog/creation/editor?not_checkout=1

有他的文章,我自己就不写这部分实战的内容了,相信大家看了之后,对ceedling理解更加深刻。

猜你喜欢

转载自blog.csdn.net/zichuanning520/article/details/130687286