zoukankan      html  css  js  c++  java
  • cmockery库详解

    1、cmockery库源码的编译链接

    下载需要FQ,没有条件的可以直接在github上找一篇比较完整的版本。
    $ ./configure
    $ make clean && make
    $ make install prefix=~/share/code/cmockery
    $ tree ~/share/code/cmockery
    install
    ├── include
    │   └── google
    │       └── cmockery.h
    ├── lib
    │   ├── libcmockery.a
    │   ├── libcmockery.la
    │   ├── libcmockery.so -> libcmockery.so.0.0.0
    │   ├── libcmockery.so.0 -> libcmockery.so.0.0.0
    │   └── libcmockery.so.0.0.0
    └── share
        └── doc
            └── cmockery-0.11
                ├── AUTHORS
                ├── ChangeLog
                ├── COPYING
                ├── index.html
                ├── INSTALL
                ├── NEWS
                └── README
     
    6 directories, 13 files
    

    安装后的目录树如上所示,包括头文件,同时提供了静态库和动态库, 和头文件,还有一些使用手册。

     2、cmockery库的使用

    cmockery使用不到2000行的代码,实现了对代码的单元测试框架。
    首先来浏览一下官方提供的example,总结一下cmockery库的功能:
    (1)运行测试 —— 参阅 run_tests.c calculator_test.c
    cmockery提供了两种方式添加一个测试用例:
        unit_test(f)
        unit_test_setup_teardown(test, setup, teardown)
    

    使用unit_test_setup_teardown的方式可以分别添加setup函数和teardown函数,可以在test之前进行初始化,测试结束之后释放资源,可以使用NULL表示空函数。

    测试框架流程:
        const UnitTest tests[] = {
            unit_test(f),
            unit_test_setup_teardown(test, setup, teardown),
        };
        run_tests(tests);
    测试结果显示如下:
    test_func: Starting test
    test_func: Test completed successfully.
    All 1 tests passed
     
    (2)断言测试 —— 参阅 assert_module_test.c assert_macro_test.c
    使用cmockery提供的assert函数:
    // If unit testing is enabled override assert with mock_assert().
    #if UNIT_TESTING
    extern void mock_assert(const int result, const char* const expression,const char * const file, const int line);
    #undef assert
    #define assert(expression) 
        mock_assert((int)(expression), #expression, __FILE__, __LINE__);
    #endif // UNIT_TESTING
    cmockery库提供了以下断言函数:
    assert_true(c) 
    assert_false(c)
    assert_int_equal(a, b) 
    assert_int_not_equal(a, b) 
    assert_string_equal(a, b) 
    assert_string_not_equal(a, b) 
    assert_memory_equal(a, b, size) 
    assert_memory_not_equal(a, b, size) 
    assert_in_range(value, minimum, maximum) 
    assert_not_in_range(value, minimum, maximum) 
    assert_in_set(value, values, number_of_values) 
    assert_not_in_set(value, values, number_of_values) 
    在测试代码时,可以适当且大量的使用断言以确保代码的可靠性。
    断言出错,将打印出错误提示,如下实例:
    get_status_code_string_test: Starting test
    "Connection dropped" != "Connection timed out"
    ERROR: src/example/assert_macro_test.c:29 Failure!
    get_status_code_string_test: Test failed.
    string_to_status_code_test: Starting test
    2 != 1
     
    (3)内存申请和释放测试 —— 参阅 allocate_module.c allocate_module_test.c
    同样需要使用cmockery提供的malloc、calloc和free函数
    #if UNIT_TESTING
    extern void* _test_malloc(const size_t size, const char* file, const int line);
    extern void* _test_calloc(const size_t number_of_elements, const size_t size,const char* file, const int line);
    extern void _test_free(void* const ptr, const char* file, const int line);
    #define malloc(size) _test_malloc(size, __FILE__, __LINE__)
    #define calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__)
    #define free(ptr) _test_free(ptr, __FILE__, __LINE__)
    #endif // UNIT_TESTING
    当内存操作不当或者malloc错误会打印出错误信息,如下实例所示:
    buffer_overflow_test: Starting test
    Guard block of 0x088e90e8 size=4 allocated by src/example/allocate_module.c:41 at 0x088e90ec is corrupt
    ERROR: src/example/allocate_module.c:43 Failure!
    buffer_overflow_test: Test failed.
    1 out of 1 tests failed!
        buffer_overflow_test
    Blocks allocated...
      0x088e90b0 : src/example/allocate_module.c:41
    Guard block of 0x088e90e8 size=4 allocated by src/example/allocate_module.c:41 at 0x088e90ec is corrupt
    ERROR: src/cmockery.c:1463 Failure!
     
    (4)模拟测试 —— 参阅 product_database_test.c customer_database_test.c
    通过expect_value和check_expected可以判断传入函数的值是不是期望的值,而will_return和mock则是对应的关系,will_return会将值放入到队列中,而每次调用mock都会取到队列前端的值。
    int test(int value, char *string)
    {
        check_expected(value);
        check_expected(string);
        return (int)mock();
    }
    void test_for_mock(void **state) {
        expect_value(test, value, 1);
        expect_string(test, string, "test");
        will_return(test, 0x123456);
        assert_int_equal(test(1, "test"), 0x123456);
    }
  • 相关阅读:
    《编译原理》-用例题理解-自顶向下语法分析及 FIRST,FOLLOW,SELECT集,LL(1)文法
    8 张脑图入门 JavaScript
    Navicat Premium 12连接Oracle时提示oracle library is not loaded的问题解决
    Spring boot 多模块项目 + Swagger 让你的API可视化
    Spring Boot -05- 多模块结构项目构建与测试(详细图文教程)IDEA 版
    JAVA 实现 QQ 邮箱发送验证码功能(不局限于框架)
    SSM 项目从搭建爬坑到 CentOS 服务器部署
    LeetCode
    有趣的位运算
    记一次向maven中央仓库提交依赖包
  • 原文地址:https://www.cnblogs.com/hancq/p/5410462.html
Copyright © 2011-2022 走看看