zoukankan      html  css  js  c++  java
  • Mac下GTest的基本使用

    Mac下GTest的基本使用

    gtest全称Google C++ Testing Framework,它是从谷歌内部诞生并受到业界追捧的一个非常优秀的测试框架,支持如自动发现测试、自定义断言、死亡测试、自动报告等诸多功能。

    本文记录Mac下安装配置gtest以及它的基本应用

    一、安装

    博主尝试用brew install 遇到了问题,于是直接源码安装

    编译安装

     git clone https://github.com/google/googletest
     cd googletest
     mkdir build && cd build
     cmake ..
     make
     make install
    

    测试代码

    CMakeLists.txt

    cmake_minimum_required(VERSION 3.0)
    set(CMAKE_CXX_STANDARD 11)
    
    project(demo)
    
    find_package(GTEST REQUIRED)
    
    add_executable(${PROJECT_NAME} main.cpp)
    
    target_link_libraries(${PROJECT_NAME} ${GTEST_LIBRARIES})
    

    main.cpp

    #include <iostream>
    #include <gtest/gtest.h>
    
    int add(int a, int b) {
        return a + b;
    }
    
    int sub(int a, int b) {
        return a - b;
    }
    
    // case1
    TEST(test, c1) {
        EXPECT_EQ(3, add(1, 2));
        EXPECT_EQ(12, add(2, 6));
    }
    
    // case2
    TEST(test, c2) {
        EXPECT_EQ(-1, sub(1, 2));
    }
    
    GTEST_API_ int main(int argc, char ** argv) {
        testing::InitGoogleTest(&argc, argv);
        return RUN_ALL_TESTS();
    }
    

    编译运行

    cmake .
    make
    ./demo
    # 输出
    ➜  build ./demo
    [==========] Running 2 tests from 1 test case.
    [----------] Global test environment set-up.
    [----------] 2 tests from test
    [ RUN      ] test.c1
    /Users/fanghao/Desktop/test/main.cpp:15: Failure
    Expected equality of these values:
      12
      add(2, 6)
        Which is: 8
    [  FAILED  ] test.c1 (0 ms)
    [ RUN      ] test.c2
    [       OK ] test.c2 (0 ms)
    [----------] 2 tests from test (0 ms total)
    
    [----------] Global test environment tear-down
    [==========] 2 tests from 1 test case ran. (0 ms total)
    [  PASSED  ] 1 test.
    [  FAILED  ] 1 test, listed below:
    [  FAILED  ] test.c1
    
     1 FAILED TEST
    

    二、基本概念

    • 断言:即assertion,检查条件是否为真,一个断言的结果有

      • sucess
      • nonfatal failure(非致命失败)
      • fatal failure(致命失败)

      这里值得注意的是后两个,nonfatal failure会指出错误,然后继续运行,由EXPECT_XX产生,fatal failure会指出错误但是终止当前测试函数,由ASSERT_XX产生,一般推荐用前者,这样一次可以查出多个问题

    • 测试样例:test case表示要测试的对象,一般TEST会有两个参数,分别是测试样例,以及测试的子case,如下面这个测试阶乘的样例,HandlesZeroInput和HandlesPositiveInput都属于FactorialTest这个测试样例

      // Tests factorial of 0
      TEST(FactorialTest, HandlesZeroInput) {
      EXPECT_EQ(1, Factorial(0));
      }
       
      // Tests factorial of positive numbers.
      TEST(FactorialTest, HandlesPositiveInput) {
      EXPECT_EQ(1, Factorial(1));
      EXPECT_EQ(2, Factorial(2));
      EXPECT_EQ(6, Factorial(3));
      EXPECT_EQ(40320, Factorial(8));
      }
      
    • 常用断言

      Fatal assertion Nonfatal assertion Verifies
      ASSERT_TRUE(condition); EXPECT_TRUE(condition); condition is true
      ASSERT_FALSE(condition); EXPECT_FALSE(condition); condition is false
      ASSERT_EQ(expected, actual); EXPECT_EQ(expected, actual); expected == actual
      ASSERT_NE(val1, val2); EXPECT_NE(val1, val2); val1 != val2
      ASSERT_LT(val1, val2); EXPECT_LT(val1, val2); val1 < val2
      ASSERT_LE(val1, val2); EXPECT_LE(val1, val2); val1 <= val2
      ASSERT_GT(val1, val2); EXPECT_GT(val1, val2); val1 > val2
      ASSERT_GE(val1, val2); EXPECT_GE(val1, val2); val1 >= val2
      ASSERT_STREQ(expected_str, actual_str); EXPECT_STREQ(expected_str, actual_str); the two C strings have the same content
      ASSERT_STRNE(str1, str2); EXPECT_STRNE(str1,str2); the two C strings have different content
      ASSERT_STRCASEEQ(expected_str, actual_str); EXPECT_STRCASEEQ(expected_str, actual_str); the two C strings have the same content,ignore case
      ASSERT_STRCASENE(str1, str2); EXPECT_STRCASENE(str1,str2); the two C strings have different content,ignore case

    三、 Test Fixture

    Test Fixture是对基本test case的封装,如果多个test需要操作类似数据,可以把他们封装在一个类里面,然后共享一些配置。

    编写Fixure步骤

    1. 建立一个类,并继承::testing::Test,并且使用protected或public限制符,以便其子类可以访问到共享的数据
    2. 在这个类中,声明你想复用的对象。
    3. 写一个SetUp函数来准备所需对象
    4. 写一个TearDown函数来释放资源
    5. 其他用法和基本的test case一样,只是用TEST_F()宏代替TEST()宏,每次调用一个TEST_F都会重新运行一次SetUp和TearDown,但但成员对象可以共享

    看一个示例应该更能说明问题

    #include <iostream>
    #include <gtest/gtest.h>
    
    class Foo
    {
      public:
        int add(int a, int b)
        {
            return a + b;
        }
        int sub(int a, int b)
        {
            return a - b;
        }
    };
    
    class FooTest : public ::testing::Test
    {
      protected:
        Foo foo; // shared object
        // SetUp && TearDown will be called for every Test Case
        virtual void SetUp()
        {
            std::cout << "Code here will be called immediately after the constructor" << std::endl;
        }
        virtual void TearDown()
        {
            std::cout << "Code here will be called immediately after each test" << std::endl;
        }
    };
    
    // Test Case 1
    TEST_F(FooTest, TestMethodAdd)
    {
        EXPECT_EQ(3, foo.add(1, 2));
    }
    
    // Test Case 2
    TEST_F(FooTest, TestMethodSub)
    {
        EXPECT_EQ(-1, foo.sub(1, 2));
    }
    
    int main(int argc, char *argv[])
    {
        ::testing::InitGoogleTest(&argc, argv);
        return RUN_ALL_TESTS();
    }
    
    # 输出
    ➜  build ./demo
    [==========] Running 2 tests from 1 test case.
    [----------] Global test environment set-up.
    [----------] 2 tests from FooTest
    [ RUN      ] FooTest.TestMethodAdd
    Code here will be called immediately after the constructor
    Code here will be called immediately after each test
    [       OK ] FooTest.TestMethodAdd (0 ms)
    [ RUN      ] FooTest.TestMethodSub
    Code here will be called immediately after the constructor
    Code here will be called immediately after each test
    [       OK ] FooTest.TestMethodSub (0 ms)
    [----------] 2 tests from FooTest (0 ms total)
    
    [----------] Global test environment tear-down
    [==========] 2 tests from 1 test case ran. (1 ms total)
    [  PASSED  ] 2 tests.
    

    四、小结

    感觉gtest还是挺优雅的,适合TDD模式,把测试和开发完全解耦。

  • 相关阅读:
    【spring】基于AspectJ的AOP
    【matlab】stanford线性回归,logistic regression 实验
    【Python】列表、字典和元组的排序
    PHP 二叉树的深度优先与广度优先遍历
    PHP 定义栈结构,实现min函数,获取栈最小元素,要求时间复杂度为O(1)
    PHP 短连接生成
    一条SQL查询访问记录表(visit_log)中某个类目(catalog_id)的访问量(visit)排前两名的记录行
    利用 p, 1p 随机数发生器知道等概率发生器
    PHP 将二叉查找树转换为双向链表,要求不能创建新节点,只能调节节点指针
    PHP 求最大递增子序列长度
  • 原文地址:https://www.cnblogs.com/fanghao/p/9616112.html
Copyright © 2011-2022 走看看