c++ - 从指定输入和预期结果的场景表生成单元测试

标签 c++ c unit-testing cpputest

我目前正在尝试为模块生成一些后期编码 UT。 该模块将输入数据分类到数据库中,如果找到匹配项,则返回适当的值。

在构建包含所有可能的输入场景及其预期结果的表格后,我发现我需要创建 50 多个测试。 由于所有测试基本相同,除了测试名称和输入,某种模板似乎适合这里,减少代码困惑。

我最初的设想是,要么创建这样一个模板并扩展到具有输入数据和预期结果的测试的宏,要么在宏的帮助下使用表示场景表的结构来包装它。 (我想 C++ 模板在这里也足够了)。

但是,我不确定这是一条正确的路径,并且想知道是否有人可以就如何解决它提出一些建议。 还有一个问题是它如何适合 TDD 方法。

这是使用 CppUTest 的想法:

#define GEN_TEST_MOD_CLASSIFIER(GROUP_NAME, TEST_NAME, PRIORITY, isCOMPRESS, isX, EXPECTING) \
TEST(GROUP_NAME, TEST_NAME) \
{ \
   int hit; \
   setupDB(PRIORITY, isCOMPRESS, isX); \
   hit = func(PRIORITY, isCOMPRESS, isX); \
   CHECK_EQUAL(EXPECTING, hit); \
}

使用示例:

GEN_TEST_MOD_CLASSIFIER(Classifier_Tests, LowPriority_NoCompress_NoX__HIT, PRIO_LOW, NOT_COMPRESS, NO_X, HIT_DB)

最佳答案

好吧,如果没有外部工具,您能做的最好的事情很可能就是使用宏。那是因为每个测试用例都需要 TEST(GROUP_NAME, TEST_NAME)

可能不是这样。您可能对每个场景没有单独的测试用例没有问题,或者 CppUTest 可能支持以编程方式添加测试用例。 在这种情况下,您可以创建一个采用输入-输出-testcasename 元组 vector 的方法。并将在每个元组上添加测试用例/运行测试。不需要宏。

类似的东西(伪代码):

typedef std::tuple<std::string, std::string, PriorityType, CompressType, ExpectedValueType> TestInfo;

void RunTest(const TestInfo& testInfo)
{
// Assuming here you're OK with this kind of test cases separation
    std::cout << "Running test" << std::get<0>(testInfo) << ", " << std::get<1>(testInfo) << std::endl;

   int hit;
   setupDB(std::get<2>(testInfo), std::get<3>(testInfo), isX);
   hit = func(std::get<2>(testInfo), std::get<3>(testInfo), isX);
   CHECK_EQUAL(std::get<4>, hit);
}

void RunTests(const TestInfo& testInfo)
{
    std::for_each(testInfo.begin(), testInfo.end(), RunTest);
}

std::vector<TestInfo> tests = { test1, test2 };
RunTests(tests);

如果这不起作用,实际上宏也可以,您也可以在那里使用基于表格的方法。看看升压预处理器(http://www.boost.org/doc/libs/1_54_0/libs/preprocessor/doc/index.html)

再次伪代码:

#include <boost\preprocessor\seq.hpp>

#define GENERATE_TEST_CASE(_ignore1_, _ignore2_, _testCaseInfoSequence_) \
    TEST(BOOST_PP_SEQ_ELEM(0, testCaseInfoSequence), BOOST_PP_SEQ_ELEM(1, testCaseInfoSequence)) \
    { \
        int hit; \
        setupDB(BOOST_PP_SEQ_ELEM(2, testCaseInfoSequence), BOOST_PP_SEQ_ELEM(3, testCaseInfoSequence), BOOST_PP_SEQ_ELEM(4, testCaseInfoSequence)); \
        hit = func(BOOST_PP_SEQ_ELEM(2, testCaseInfoSequence), BOOST_PP_SEQ_ELEM(3, testCaseInfoSequence), BOOST_PP_SEQ_ELEM(4, testCaseInfoSequence)); \
        CHECK_EQUAL(BOOST_PP_SEQ_ELEM(5, testCaseInfoSequence), hit); \
    }

#define TESTCASES \
    ( \
        (Group1)(Test1)(prio1)(isCompress1)(isX1)(expectedVal1) \
        (Group1)(Test2)(prio2)(isCompress2)(isX2)(expectedVal2) \
    ) 

// This statement will generate all tests cases in defined in TESTCASES sequnce.
BOOST_PP_SEQ_FOREACH(GENERATE_TEST_CASE, _ignore_, TESTCASES);

关于c++ - 从指定输入和预期结果的场景表生成单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18445570/

相关文章:

c++ - LEDA 库(C++ 库)设置 linux

c++ - 带有 O2 的 clang++ 的 undefined reference

c - 在C中实现递归调用时遇到问题

python - Django:跨多个文件拆分测试,但共享同一个数据库?

c++ - QTableView,如何更改拖动多个项目的显示

c++ - 为什么从不同的 "bases"调用 getter 和 setter?

c - 内存中数据的有符号和无符号表示?

c - 客户端的 read() 失败 C

java - Junit 测试空方法

python-3.x - Python 测试对实例化为另一个类中的变量的类方法的调用