自定义单元测试++

发布于 2024-12-01 16:35:08 字数 1327 浏览 3 评论 0原文

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

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

我现在已经编写了相当多的测试,每次运行测试构建时它们都会执行,这当然是预期的。我什至定义了自己的 TestReporter 类,它为我提供了比默认值更多的有关每个测试的信息 - 它在最后打印每个测试所花费的时间,并且还具有颜色编码的测试开始和测试结束消息这样我就可以更轻松地浏览测试输出。

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

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

唔。看起来这只是一个链接列表。我想我可以去毁掉它...... O(m*n) 搜索,m=总测试,n=指定测试。出色地。我不断回答自己的问题。 Mods:我将发布我的解决方案实施的答案。希望它能为某人节省二十分钟。

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

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

编辑:我想我已经明白了。哇,第一次涉足模板编程。

I'm asking this with hopes that somebody has been in my shoes and has some ideas. Trying to avoid reinventing the wheel, so to speak.

I'm using UnitTest++: http://unittest-cpp.sourceforge.net/UnitTest++.html

I've got quite a few tests written by now, and they all execute every time I run the test build, which of course is to be expected. I even defined my own TestReporter class which provides me with a bit more information about each test than the default -- it prints the time it took for each test at the end of it, and also has color-coded test begin and test end messages so it's easier for me to navigate the test output.

But I'm getting to a point where the sheer number of tests dumps out so much output that my console's buffer doesn't even hold the results from the first few tests anymore, and I'm tired of changing that setting. So I'd like to be able to specify as an optional arguments to running the test build the tests I'd like to run and skip the others.

The code for UnitTest++ is fairly straightforward and I admit i could probably figure it out if I stared at it some more but surely somebody out there's already figured this out? I'm trying to come up with a way to connect my argv[] with Test::GetTestList(). I'd like to filter the test list with cmdline arguments and run those tests only.

Hmm. Looks like it's just a linked list. I guess I can just go mutilate it... O(m*n) search, m=total tests, n=specified tests. Well. I keep answering my own questions. Mods: I will post an answer with my solution's implementation. Hopefully it'll save somebody twenty minutes.

Edit: It looks like I really really should use the Predicate thingy:

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();
}   

That way I can just directly use RunTestsIf().

edit: I think i figured it out. Wow, first foray into template programming.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

佼人 2024-12-08 16:35:08

这是我的解决方案:

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

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

Here's my solution:

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

Only thing slightly bothers me with this is there's no clean way to check if any given test matchers didn't end up matching anything.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文