我想要的是希望有人能够帮助我,并且有一些想法。试着避免重新发明轮子,可以这么说。
我正在使用UnitTest ++:http://unittest-cpp.sourceforge.net/UnitTest++.html
我现在已经编写了很多测试,并且每次运行测试版本时它们都会执行,这当然是可以预料的。我甚至定义了我自己的TestReporter类,它为我提供了有关每个测试的更多信息而不是默认值 - 它打印了每个测试结束时所花费的时间,还有颜色编码的测试开始和测试结束消息所以我更容易导航测试输出。
但是我已经达到了这样一个程度,即测试的绝对数量会输出很多输出,我的控制台的缓冲区甚至不能保留前几个测试的结果,而且我已经厌倦了改变这个设置。所以我希望能够指定作为运行测试的可选参数构建我想要运行的测试并跳过其他测试。
UnitTest ++的代码相当简单,我承认,如果我再盯着它,我可能会想出来但是肯定有人已经把它想出来了吗?我试图想出一种方法来连接我的argv []和Test :: GetTestList()。我想用cmdline参数过滤测试列表并仅运行这些测试。
嗯。看起来它只是一个链表。我想我可以把它毁掉...... O(m * n)搜索,m =总测试,n =指定测试。好。我一直在回答自己的问题。 Mods:我将在我的解决方案的实现中发布答案。希望它能节省20分钟。
编辑:看起来我真的应该使用谓词的东西:
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()
。
编辑:我想我想通了。哇,首先涉足模板编程。
答案 0 :(得分: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.
}
}
只有事情让我感到困扰,因为没有干净的方法来检查任何给定的测试匹配器是否最终没有匹配任何东西。