• (二)cmockery中run_tests.c分析


    所分析的run_tests.c文件位于 工程中的 cmockery/src/example/ 目录下,仅仅只有十几行代码,不过可以通过这十几行代码的分析达到管中窥豹的效果;
    run_tests.c:
    1. #include <stdarg.h>
    2. #include <stddef.h>
    3. #include <setjmp.h>
    4. #include <cmockery.h>
    5. // A test case that does nothing and succeeds.
    6. void null_test_success(void **state) {
    7. }
    8. int main(int argc, char* argv[]) {
    9. const UnitTest tests[] = {
    10. unit_test(null_test_success),
    11. };
    12. return run_tests(tests);
    13. }

    对于代码中出现的几个部件进行分解开来看,如下:
    UnitTest结构体:
    1. // 函数原型用于setup, test and teardown functions.
    2. typedef void (*UnitTestFunction)(void **state);
    3. // 单元测试函数的类型
    4. typedef enum UnitTestFunctionType {
    5. UNIT_TEST_FUNCTION_TYPE_TEST = 0,
    6. UNIT_TEST_FUNCTION_TYPE_SETUP,
    7. UNIT_TEST_FUNCTION_TYPE_TEARDOWN,
    8. } UnitTestFunctionType;
    9. /*
    10. * 存储一个单元测试函数包括其函数名和类型
    11. * 注意:每设置一个函数必须有一个teardown函数对应,可以指定一个NULL函数指针
    12. */
    13. typedef struct UnitTest {
    14. const char* name;
    15. UnitTestFunction function;
    16. UnitTestFunctionType function_type;
    17. } UnitTest;
    可以看到这个结构体中所包含的内容只有一个函数名,一个函数指针,一个函数的类型枚举;

    unit_test:是一个宏体,定义如下:
    1. // 初始化一个单元测试结构体.
    2. #define unit_test(f) { #f, f, UNIT_TEST_FUNCTION_TYPE_TEST }
    所有上面main.c中的代码行:unit_test(null_test_success),按照宏定义进行展开后表示如下:
    {"null_test_success", null_test_success, UNIT_TEST_FUNCTION_TYPE_TEST},
    所以正好填充了结构体数组的第一个元素的各个值;

    run_tests:是一个宏体,定义如下:
    1. /*
    2. * 运行通过UnitTest结构体数组指定的测试,下面的样例
    3. * 以unit_test宏来描述了这个宏的用法
    4. *
    5. * void Test0();
    6. * void Test1();
    7. *
    8. * int main(int argc, char* argv[]) {
    9. * const UnitTest tests[] = {
    10. * unit_test(Test0);
    11. * unit_test(Test1);
    12. * };
    13. * return run_tests(tests);
    14. * }
    15. */
    16. run_tests(tests) _run_tests(tests, sizeof(tests) / sizeof(tests)[0])

    将代码中run_tests(tests);展开之后内容为:_run_tests(tests, 1);
    先简要介绍该函数的功能:
        _run_tests函数中根据tests中元素的赋值情况,即类型和函数指针,进行不同的分支并调用_run_test运行该元素的函数指针所指向的函数体。并将运行的结果进行返回。
    在这个过程中还会将函数执行的状态进行记录,其中包括了链表,内存分配,信号等相关的操作。后续会进行这个功能详细的分析。





















  • 相关阅读:
    海尔大数据精准营销平台(内部资料)
    马化腾做的PPT:产品设计与用户体验
    网站上线后,第一次完成线上线下整个环节
    灵感不断
    redis命令
    Redis持久化实践及灾难恢复模拟
    [转]创业公司常见的25个法律问题
    用python语言编写网络爬虫
    Python3常用网络编程模块介绍
    Python3数据库模块(sqlite3,SQLite3)
  • 原文地址:https://www.cnblogs.com/cfzhang/p/612f2868819ea56d10da291fbea1c4ae.html
Copyright © 2020-2023  润新知