在我的项目中,我们使用gtest模拟块盒测试。出于这个原因,我们实现了一个mockMain()函数,其中包含应该在黑盒内部的所有相关代码。然后我们通过gtest使用TEST_F函数来执行main并验证它生成的输出。现在的问题是:我想编写死亡测试,因为对于某些输入,程序应该退出。不幸的是,当我执行死亡测试时,它会无限循环。由于实际的程序非常庞大,我试图捕捉下面代码中所发生事情的本质。它和主程序有同样的问题。
我发现在Windows上,死亡测试是在threadsafe中执行的。模式,重新运行整个程序。有办法改变这一点吗?
main.cpp
bool runBlackboxTest = true;
int main(int argc, char *argv[])
{ //Only execute tests if flag is enabled
if(runBlackboxTest){
RectangleBlackboxTest::runAllTests();
exit(0);
}
Rectangle oneRect(12.1, 7.4);
std::cout << "Area: " << oneRect.getArea() << std::endl;
return 0;
}
Rectangle.cpp
Rectangle::Rectangle(double a, double b){
this->side_a = a;
this->side_b = b;
this->area = a*b;
}
double Rectangle::getArea(){
return this->area;
}
double Rectangle::rectExit(){
std::cout << "Exiting program." << std::endl;
exit(1);
return 0;
}
RectangleBlackboxTest.cpp
using RectangleBlackboxDeathTest = RectangleBlackboxTest;
int RectangleBlackboxTest::runAllTests(){
testing::InitGoogleTest();
return RUN_ALL_TESTS();
}
//Just some example functinoality
void RectangleBlackboxTest::mockMain(){
double a, b;
srand(time(NULL));
a = double(rand() % 100 + 1) / 17;
b = double(rand() % 100 + 1) / 11;
this->testingRect = new Rectangle(a, b);
std::cout << "a: " << a << " b: " << b << " Area: " << this->testingRect->getArea() << std::endl;
}
//Imitating an exit in the mockMain()
void RectangleBlackboxTest::mockMainWithExit(){
this->mockMain();
this->testingRect->rectExit();
}
void RectangleBlackboxTest::TearDown(){
delete this->testingRect;
}
//This is the part that loops indefinitely
TEST_F(RectangleBlackboxDeathTest, firstDeathTest){
EXPECT_EXIT(mockMainWithExit(), testing::ExitedWithCode(1), ".*");
}
对于有同样问题的人:
主要问题在testing::InitGoogleTest()
。
当gtest发现一个死亡测试时,它在Windows下使用createProcessA(...)
创建一个新进程,并传递额外的参数,以确保子进程只执行当前的死亡测试。当这些参数没有在子进程中给testing::InitGoogleTest()
时,就会导致问题。在这种情况下,它没有接收到只执行死亡测试的信息,而是再次开始运行整个测试代码,从而导致递归。
TLDR:
将命令行参数从main(int argc, char *argv[])
传递到testing::InitGoogleTest()
:
testing::InitGoogleTest(argc, argv)