关于c ++:自定义unittest ++

customizing unittest++

我问这个有希望,有人一直在我的鞋子,并有一些想法。试着避免重新发明轮子,可以这么说。

我正在使用UnitTest ++:http://unittest-cpp.sourceforge.net/UnitTest++.html

我现在已经编写了很多测试,每次运行测试版本时它们都会执行,这当然是可以预期的。我甚至定义了我自己的TestReporter类,它为我提供了有关每个测试的更多信息而不是默认值 - 它打印了每个测试结束时所花费的时间,还有颜色编码的测试开始和测试结束消息所以我更容易导航测试输出。

但是我已经到了这样一个地步:大量的测试输出了如此多的输出,我的控制台的缓冲区甚至不再保留前几个测试的结果,而且我已经厌倦了改变那个设置。所以我希望能够指定作为运行测试的可选参数构建我想要运行的测试并跳过其他测试。

UnitTest ++的代码相当简单,我承认如果我再盯着它,我可能会想出来但是肯定有人已经想到这个了吗?我试图想出一种方法来连接我的argv []和Test :: GetTestList()。我想用cmdline参数过滤测试列表并仅运行这些测试。

嗯。看起来它只是一个链表。我想我可以把它毁掉...... O(m * n)搜索,m =总测试,n =指定测试。好。我一直在回答自己的问题。 Mods:我将在我的解决方案的实现中发布答案。希望它能节省20分钟。

编辑:看起来我真的应该使用Predicate thingy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
template <class Predicate>
int RunTestsIf(TestList const& list, char const* suiteName,
               const Predicate& predicate, int maxTestTimeInMs) const
{
    Test* curTest = list.GetHead();

    while (curTest != 0)
    {
        if (IsTestInSuite(curTest,suiteName) && predicate(curTest))
        {
            RunTest(m_result, curTest, maxTestTimeInMs);
        }

        curTest = curTest->next;
    }

    return Finish();
}

这样我就可以直接使用RunTestsIf()

编辑:我想我想通了。哇,首先涉足模板编程。


这是我的解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
namespace UnitTest {
    class ListFilter {
        char **list;
        int n;
    public:
        ListFilter(char **list_, int count) {
            list = list_; n = count;
        }
        bool operator()(const Test* const t) const {
            for (int i=0;i<n;++i) {
                std::string dot_cpp_appended = std::string(list[i]) +".cpp";
                if (!strcasecmp(t->m_details.testName, list[i]) ||
                        !strcasecmp(t->m_details.suiteName, list[i]) ||
                        !strcasecmp(t->m_details.filename, list[i]) ||
                        !strcasecmp(t->m_details.filename, dot_cpp_appended.c_str())) {
                    // erring on the side of matching more tests
                    return true;
                }
            }
            return false;
        }
    };

    int RunTheseTests(char ** list, int n) {
        TestReporterStdout reporter;
        TestRunner runner(reporter);
        return runner.RunTestsIf(Test::GetTestList(), NULL, ListFilter(list,n), 0);
    }
}

int main(int argc, char *argv[]) {
    if (argc == 1) {
        UnitTest::RunAllTests();
    } else {
        UnitTest::RunTheseTests(argv+1, argc-1); // skip the program's name itself.
    }
}

只有事情让我感到困扰的是,没有干净的方法来检查任何给定的测试匹配器是否最终没有匹配任何东西。