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模式,把测试和开发完全解耦。

  • 相关阅读:
    Open source cryptocurrency exchange
    Salted Password Hashing
    95. Unique Binary Search Trees II
    714. Best Time to Buy and Sell Stock with Transaction Fee
    680. Valid Palindrome II
    Java compiler level does not match the version of the installed Java project facet.
    eclipse自动编译
    Exception in thread "main" java.lang.StackOverflowError(栈溢出)
    博客背景美化——动态雪花飘落
    java九九乘法表
  • 原文地址:https://www.cnblogs.com/fanghao/p/9616112.html
Copyright © 2011-2022 走看看