如何使用Google Test在main()函数中的特定位置调用特定的测试函数?

时间:2014-01-23 13:50:40

标签: c++ unit-testing testing googletest

我正在使用TDD和Google Test进行涉及数值模拟的项目。数据的状态在main函数的循环内发生变化,但每次更改后都需要满足要求。如果测试用例满足所有要求,则通过验收测试:

while(simulation)
     modify simulation data
     FIRST_TEST()
     some other simulation operations
     SECOND_TEST()

通常调用RUN_ALL_TESTS()的GTest primer个状态。 Advanced Guide显示如何通过从RUN_ALL_TESTS中过滤掉测试来运行子测试。但是,我想知道如何单独调用测试。

否则每次我需要在上面的伪代码片段中进行FIRST_和SECOND_等新测试时,我都需要编写一个新的验收测试应用程序。

更多背景知识:我正在使用OpenFOAM框架进行计算流体动力学,因此在main之外创建全局装置不是一种选择。模拟应用程序需要运行目录和配置文件,并且main中的全局对象是相互关联的(需要彼此进行初始化)。此类应用程序的一个示例是 OpenFOAM-2.2.x

进一步说明

我接受了接受的答案以及关于如何在another question on Stack Overflow上的测试中使用argc和argv作为全局变量的答案,我把它归纳为这个可编译的小模型,也许有人发现它很有用:

#include <gtest/gtest.h>
#include <iostream>

class Type 
{
    int value_ = 0;
    int times_ = 1; 

    public: 

        Type(int x) : value_(x) {}; 

        void operator()(){
            if (times_ < 10) {
                ++times_; 
                value_ *= times_; 
            }
        }

        int value () const { return value_; } 
}; 

class mySeparatedTests : public ::testing::Test 
{
    protected:

      template<typename Type>
      void TEST_ONE(Type const &t)
      {
          ASSERT_TRUE((t.value() % 2) == 0); 
      }

      template<typename Type> 
      void TEST_TWO(Type const & t)
      {
          ASSERT_TRUE((t.value() - 5) > 0); 
      }
};

TEST_F(mySeparatedTests, testName)
{
    extern char** globalArgv; 
    char** argv = globalArgv;

    // Simulation parameters and objects requiring argc and argv for initialization. 
    int simulationEndTime;  

    *argv[1] >> simulationEndTime;  

    Type typeObject(*argv[2]); 

    TEST_ONE(typeObject); 

    // Simulation loop. 
    for (int i = 0; i < simulationEndTime; ++i)
    {
        typeObject(); 

        TEST_TWO(typeObject); 
    }
}

int globalArgc; 
char** globalArgv; 

int main(int argc, char **argv)
{
    ::testing::InitGoogleTest(&argc, argv);

    globalArgc = argc; 
    globalArgv = argv; 

    return RUN_ALL_TESTS(); 

    return 0; 
}

如接受的答案中所述,此方法将模拟代码从main移植到TEST_F中,并使用mySeparatedTests类函数定义单个测试,然后可以在任何地方调用。这是编译的:

g++ -std=c++11 -l gtest main.cpp  -o main

测试失败/通过取决于解析的参数对;

这失败了:

./main 1 1 

这成功了:

./main 2 2 

注意:我知道发生了char / int转换;这只是为了展示如何拿起args。

1 个答案:

答案 0 :(得分:4)

我的猜测是你略微误解了googletest的作用。测试序列的控制由测试运行器控制。你可以做的是用你的while循环定义一个单独的测试,区别在于你的FIRST_TEST等是一个夹具的功能,有一些断言。例如:

而不是:

int main(...) { ... while (...) PERFORM_TEST("A"); ... }
TEST(A,some_test) {}

你可以选择标准的googletest runner main并定义:

// fixture
class MyTest : public ::testing::Test {
protected:
  bool simulation() {
    ///...
  }

  void TEST_A() {
    ASSERT_EQ(...);
    //...
  }

  void TEST_B() {
    ASSERT_EQ(...);
    //...
  }
  ///
};

// the test "runner"
TEST_F(MyTest, main_test) {
  while (simulation()) {
    // modify simulation data
    TEST_A();
    // some other simulation operations
    TEST_B();
  }
}