zoukankan      html  css  js  c++  java
  • (六)cmockery中的assert_macro分析

        所分析的assert_macro.c和assert_macro_test.c文件位于 工程中的 cmockery/src/example/ 目录下,是关于assert方法的一个应用,可以进行判断指定类型数据的逻辑关系的断言,提供了一组函数如下:
    1. 断言整数相等或者不相等
    2. assert_int_equal(a, b)
    3. assert_int_not_equal(a, b)
    4. 断言字符串相等或者不相等
    5. assert_string_equal(a, b)
    6. assert_string_not_equal(a, b)
    7. 断言内存相等或者不相等
    8. assert_memory_equal(a, b, size)
    9. assert_memory_not_equal(a, b, size)
    10. 断言数据是不是在最大最小值之间
    11. assert_in_range(value, minimum, maximum)
    12. assert_not_in_range(value, minimum, maximum)
    13. 断言数据是不是在集合中
    14. assert_in_set(value, values, number_of_values)
    15. assert_not_in_set(value, values, number_of_values)
    assert_macro.c
    1. #include <string.h>
    2. static const char* status_code_strings[] = {
    3. "Address not found",
    4. "Connection dropped",
    5. "Connection timed out",
    6. };
    7. const char* get_status_code_string(const unsigned int status_code) {
    8. return status_code_strings[status_code];
    9. };
    10. unsigned int string_to_status_code(const char* const status_code_string) {
    11. unsigned int i;
    12. for (i = 0; i < sizeof(status_code_strings) /
    13. sizeof(status_code_strings[0]); i++) {
    14. if (strcmp(status_code_strings[i], status_code_string) == 0) {
    15. return i;
    16. }
    17. }
    18. return ~0U;
    19. }
    这个文件中有两个函数,get_status_code_string和string_to_status_code;
    其中
        get_status_code_string函数就是简单的根据传入整数值作为索引,然后找到数组中的字符串并返回。
        string_to_status_code函数是根据传入的字符串和字符串数组中的状态值进行比较,如果找到则返回索引值,如果没有找到则返回0xffffffff

    assert_macro_test.c
    1. #include <stdarg.h>
    2. #include <stddef.h>
    3. #include <setjmp.h>
    4. #include "cmockery.h"
    5. extern const char* get_status_code_string(const unsigned int status_code);
    6. extern unsigned int string_to_status_code(
    7. const char* const status_code_string);
    8. /* This test will fail since the string returned by get_status_code_string(0)
    9. * doesn't match "Connection timed out". */
    10. void get_status_code_string_test(void **state) {
    11. assert_string_equal(get_status_code_string(0), "Address not found");
    12. assert_string_equal(get_status_code_string(1), "Connection timed out");
    13. }
    14. // This test will fail since the status code of "Connection timed out" isn't 1
    15. void string_to_status_code_test(void **state) {
    16. assert_int_equal(string_to_status_code("Address not found"), 0);
    17. assert_int_equal(string_to_status_code("Connection timed out"), 1);
    18. }
    19. int main(int argc, char *argv[]) {
    20. const UnitTest tests[] = {
    21. unit_test(get_status_code_string_test),
    22. unit_test(string_to_status_code_test),
    23. };
    24. return run_tests(tests);
    25. }

    有两个单元测试函数get_status_code_string_test和string_to_status_code_test;

    对于assert_string_equal,是一个宏定义如下:
    1. #define assert_string_equal(a, b)
    2. _assert_string_equal((const char*)(a), (const char*)(b), __FILE__,
    3. __LINE__)

    将函数assert_string_equal(get_status_code_string(0), "Address not found");带入之后为
    _assert_string_equal((const char*)(get_status_code_string(0)), (const char*)("Address not found"), __FILE__, __LINE__)
    1. void _assert_string_equal(const char * const a, const char * const b,
    2. const char * const file, const int line) {
    3. if (!string_equal_display_error(a, b)) {
    4. _fail(file, line);
    5. }
    6. }
    最终这个函数的调用形式为:_assert_string_equal((const char*)("Address not found"), (const char*)("Address not found"), __FILE__, __LINE__)
    1. static int string_equal_display_error(
    2. const char * const left, const char * const right) {
    3. if (strcmp(left, right) == 0) {
    4. return 1;
    5. }
    6. print_error(""%s" != "%s" ", left, right);
    7. return 0;
    8. }
    将参数带入只有 left=right所以会返回1;不会有任何的报错信息。
    而以同样的方式带入assert_string_equal("Connection dropped", "Connection timed out");则会在string_equal_display_error函数中打印error信息并且返回0,然后再
    _assert_string_equal函数中调用_fail函数,打印日志信息,并且longjmp跳转到setjmp位置,进行下一个测试的执行。

    对于assert_int_equal这个宏来说,定义如下:
    1. #define LargestIntegralType unsigned long long
    2. #define cast_to_largest_integral_type(value)
    3. ((LargestIntegralType)((unsigned)(value)))
    4. #define assert_int_equal(a, b)
    5. _assert_int_equal(cast_to_largest_integral_type(a),
    6. cast_to_largest_integral_type(b),
    7. __FILE__, __LINE__)

    将程序中的函数还原到宏体中如下:
    _assert_int_equal((unsigned long long)(unsigned)(0),(unsigned long long)(unsigned)(0), __FILE__, __LINE__);
    1. void _assert_int_equal(
    2. const LargestIntegralType a, const LargestIntegralType b,
    3. const char * const file, const int line) {
    4. if (!values_equal_display_error(a, b)) {
    5. _fail(file, line);
    6. }
    7. }


    1. static int values_equal_display_error(const LargestIntegralType left,
    2. const LargestIntegralType right) {
    3. const int equal = left == right;
    4. if (!equal) {
    5. print_error(LargestIntegralTypePrintfFormat " != "
    6. LargestIntegralTypePrintfFormat " ", left, right);
    7. }
    8. return equal;
    9. }
    很显然这个函数执行到这里的时候left==right==0;会赋值给equal为1,即返回值为1.正常结束。

    而在执行_assert_int_equal((unsigned long long)(unsigned)(2),(unsigned long long)(unsigned)(1), __FILE__, __LINE__);的时候会返回0,导致在_assert_int_equal函数中调用_fail函数,跳转到setjmp位置进行下一个测试。

    最后这样例程序的运行结果如下:


















  • 相关阅读:
    SQL语句中----删除表数据drop、truncate和delete的用法
    Sql server 中的bulk insert语句使用
    [Err] 42000
    abstract class和interface的异同
    浅谈Overload和Override
    public,private,protected,以及default时的区别
    Integer与int的区别
    static关键字
    "=="和equals方法究竟有什么区别
    final关键字
  • 原文地址:https://www.cnblogs.com/cfzhang/p/d75576559e58c3d0708d2d99dfe46947.html
Copyright © 2011-2022 走看看