1

我问这个是希望有人站在我的立场上并有一些想法。可以这么说,试图避免重新发明轮子。

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

我现在已经编写了很多测试,每次我运行测试构建时它们都会执行,这当然是意料之中的。我什至定义了我自己的 TestReporter 类,它为我提供了比默认测试更多的信息——它在结束时打印每个测试所花费的时间,并且还有颜色编码的测试开始和测试结束消息所以我更容易浏览测试输出。

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

UnitTest++ 的代码相当简单,我承认如果我再多看一些,我可能会弄明白,但肯定有人已经弄明白了?我正在尝试想办法将我的 argv[] 与 Test::GetTestList() 连接起来。我想用命令行参数过滤测试列表并只运行这些测试。

唔。看起来它只是一个链表。我想我可以去破坏它... O(m*n) 搜索,m=total tests,n=specified tests。好。我一直在回答我自己的问题。Mods:我将发布我的解决方案实施的答案。希望它会为某人节省二十分钟。

编辑:看起来我真的应该使用谓词的东西:

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().

编辑:我想我想通了。哇,第一次涉足模板编程。

4

1 回答 1

0

这是我的解决方案:

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.
    }
}

唯一让我有点困扰的是没有干净的方法来检查任何给定的测试匹配器是否最终没有匹配任何东西。

于 2011-08-27T09:08:12.623 回答