Google使用全局向量测试ValuesIn

时间:2015-08-05 15:53:27

标签: c++ unit-testing googletest

我正在尝试根据目录中的配置文件运行一堆谷歌测试。这样我就可以添加一个新文件并运行测试,而无需将其添加到我的参数化测试并重新编译。这是我的代码:

class C:
    def __init__ (self, b, listOfB):
        self.c = c
        self.listOfB = list(listOfB)
    @staticmethod
    def decode(jsonMap):
        return C(jsonMap['c'], [ B.decode(x) for x in jsonMap['listOfB'] ])

当我运行它时,它显示正在运行0个测试,即使向量表示其大小为2。为什么这些参数化测试没有运行?

typedef std::pair<QString, int> TestParam;

QString generatedLogic;

std::vector<TestParam> badExpressionTests;

class LogicBuilderTest : public ::testing::TestWithParam<TestParam> {};

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

    ::generatedLogic = "/home/mitydsp/trunk/System/logicExecutionEngine/engine/include/GeneratedLogic.h";

    QString dir = "/home/mitydsp/trunk/System/logicExecutionEngine/unittest/expressions/bad/";
    QDirIterator it(dir, QStringList() << "*.txt", QDir::Files, QDirIterator::Subdirectories);

    while (it.hasNext()) {
        QString path = it.next();
        QStringList nameParts = it.fileName().split("_");
        int exitCode = nameParts[0].toInt();
        ::badExpressionTests.push_back(TestParam(path, exitCode));
    }

    std::cout << "Size of vector: " << badExpressionTests.size() << std::endl;

    return RUN_ALL_TESTS();
}

/**
 * Run parameterized test
 */
TEST_P(LogicBuilderTest, TestExitWithCode)
{    
    ::testing::FLAGS_gtest_death_test_style = "threadsafe";

    // Simulate fake main()
    char  arg0[] = "logicTest";
    char* argv[] = { &arg0[0], NULL };
    int argc = (int)(sizeof(argv) / sizeof(argv[0])) - 1;

    EXPECT_EXIT({
        // Need to run Qt Application because logic builder uses async QTimer::singleShot()
        QCoreApplication app(argc, argv);

        // Create a logic builder instance
        LogicBuilder logicBuilder(
            (int) ParameterStoreInterface::DEFAULT_PARAM_STORE_VALUES_KEY,
            (int) ParameterStoreInterface::DEFAULT_PARAM_STORE_NAMES_KEY,
            (int) ParameterStoreInterface::DEFAULT_PARAM_STORE_LOCK_KEY,
            QString(GetParam().first),
            QStringList(""),
            QStringList(generatedLogic),
            QString(LogicBuilder::DEFAULT_INTERMEDIATE_DIR),
            QString(LogicBuilder::DEFAULT_OUTPUT_SRC),
            QString(LogicBuilder::DEFAULT_OUTPUT_LIB),
            true );

        app.exec();
    }, ::testing::ExitedWithCode(GetParam().second), "");
} 

INSTANTIATE_TEST_CASE_P(TestBadExpressions, LogicBuilderTest,
                        ::testing::ValuesIn(::badExpressionTests));

最初我是通过手动定义配置文件来运行测试但我不喜欢这样:

Size of vector: 2
[==========] Running 0 tests from 0 test cases.
[==========] 0 tests from 0 test cases ran. (0 ms total)
[  PASSED  ] 0 tests.

3 个答案:

答案 0 :(得分:2)

我花了最后一小时试图解决这个问题,然后我发布后立即提出解决方案。我会把它留在这里,因为它可能在将来帮助某人:

不是尝试在main中创建文件列表,而是传递ValuesIn一个加载文件并返回向量的函数。

std::vector<TestParam> GetFilesInDir() 
{
    std::vector<TestParam> values;
    QString dir = "/home/mitydsp/trunk/System/logicExecutionEngine/unittest/expressions/bad/";
    QDirIterator it(dir, QStringList() << "*.txt", QDir::Files, QDirIterator::Subdirectories);

    while (it.hasNext()) {
        QString path = it.next();
        QStringList nameParts = it.fileName().split("_");
        int exitCode = nameParts[0].toInt();
        values.push_back(TestParam(path, exitCode));
    }

    return values;
}

INSTANTIATE_TEST_CASE_P(TestBadExpressions, LogicBuilderTest,
                        ::testing::ValuesIn(GetFilesInDir()));

感谢Maksim Solovjov提醒我在main之前正在执行INSTANTIATE_TEST_CASE_P宏。

答案 1 :(得分:1)

我们在这个问题上花了几个小时,并认为这段代码会有所帮助。

#include <iostream>
#include <string>
#include <vector>
using namespace std;
#include "gtest/gtest.h"

GTEST_API_ main( int argc, char* argv[] ) {
   testing::InitGoogleTest( &argc, argv );
   return RUN_ALL_TESTS();
}

struct test_parms_s {
   string         name;             // Simple name of this test
   string         description;      // Description of this test
   void*          function_parms;   // Pointer to test function specific data
};

std::vector<test_parms_s*> BuildTestData() {
   test_parms_s* pTestDataA = new test_parms_s(); 
   test_parms_s* pTestDataB = new test_parms_s(); 
   test_parms_s* pTestDataC = new test_parms_s();

   pTestDataA->name.assign("testA");
   pTestDataA->description.assign("testA_desc");
   pTestDataA->function_parms = NULL;

   pTestDataB->name.assign("testB");
   pTestDataB->description.assign("testB_desc");
   pTestDataB->function_parms = NULL;

   pTestDataC->name.assign("testC");
   pTestDataC->description.assign("testC_desc");
   pTestDataC->function_parms = NULL;

   std::vector<test_parms_s*> values;
   values.push_back(pTestDataA);
   values.push_back(pTestDataB);
   values.push_back(pTestDataC);
   cout << "BuildTestData" << endl;

   return values;
}
//------------------------------------------------------------------------
class Testy {
  private:
     string       testname_;
  public:
     Testy( string testname );
     ~Testy();
     string   GetTestName();
     void     SetTestName( string testname );
};
Testy::Testy( string testname ) {
   testname_.assign(testname);
}
Testy::~Testy() {}
string Testy::GetTestName() { return testname_; }
void Testy::SetTestName( string testname ) { testname_ = testname; }
//------------------------------------------------
class TestFixture : public ::testing::TestWithParam<test_parms_s*> {
   protected:
     Testy* testy;      
     virtual void SetUp() {
        testy = new Testy( "Test");
     }
     virtual void TearDown() {
        delete( testy );
     }
};
//------------------------------------------------
TEST_P( TestFixture, ParamTest ) {
   test_parms_s* pTestParms = GetParam();
   cout << pTestParms->name << endl;
} 
//------------------------------------------------
INSTANTIATE_TEST_CASE_P( TestFixture_instance, TestFixture,                     
                         ::testing::ValuesIn(BuildTestData()));
//========================================================================

输出将是

BuildTestData
[==========] Running 3 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 3 tests from TestFixture_instance/TestFixture
[ RUN      ] TestFixture_instance/TestFixture.ParamTest/0
testA
[       OK ] TestFixture_instance/TestFixture.ParamTest/0 (0 ms)
[ RUN      ] TestFixture_instance/TestFixture.ParamTest/1
testB
[       OK ] TestFixture_instance/TestFixture.ParamTest/1 (0 ms)
[ RUN      ] TestFixture_instance/TestFixture.ParamTest/2
testC
[       OK ] TestFixture_instance/TestFixture.ParamTest/2 (0 ms)
[----------] 3 tests from TestFixture_instance/TestFixture (0 ms total)

[----------] Global test environment tear-down
[==========] 3 tests from 1 test case ran. (0 ms total)
[  PASSED  ] 3 tests.

答案 2 :(得分:0)

我不是手动实例化Google测试的专家,但是你做它的方式不可行:你在静态上下文中调用INSTANTIATE_TEST_CASE_P,所以它在main之前被评估被称为。

您可以尝试在RUN_ALL_TESTS之前移动实例化;但是,我不知道那个宏做了什么,这可能是非法的。在这种情况下,我认为您无法以动态方式使用INSTANTIATE_TEST_CASE_P创建测试。