CppUnit的缺陷与改进

CppUnit的缺陷

上一篇我们介绍了CppUnit以及它的一些重要理念(参见《CppUnit与单元测试》)。然而在使用CppUnit的过程中,我还是遇到了一些不如意的地方。这里,我们就要讨论下我看到的CppUnit存在的一些不足,以及我在StdExt中对它作出的改进。

CppUnit提供了自动化、安全可控的执行环境。这是它的精华。然而它的问题在于,在测试案例执行失败,也就是说当模块存在bug时,没有一个很好的方式去跟踪它。展开来说,主要的问题有两点:

1、虽然CppUnit的出错报告中给出了错误所在的文件以及行号,但是这个信息并不方便,也不充足。

不方便之处在于,我得找到相应的文件,然后打开它,定位到出错的行,设置断点,跟踪。有没有可能做得更加方便一些?不充足之处在于,也许出错行并不是每次执行都出错,而是在n次执行的时候出错。那么直接跑到出错行设断点,不是什么好主意。

我们知道,MFC的ASSERT(或者ATL的ATLASSERT)很好用,因为它在断言失败时可以停下来,进入调试状态。有没有可能, CPPUNIT_ASSERT也可以在出错的时候停下来?嗯,好像不行?CppUnit强调的是自动化,如果停下来就麻烦了。——各位读者想到可什么主意了?

2、一个测试程序有很多个测试案例,在某个测试函数存在bug时,其实我们跟踪调试的时候,并不喜欢所有的案例一起执行,而只希望执行有问题的案例。

特别是每个案例执行时间如果较长,那么漫长的等待也许让你有挫伤感。另外的问题是,也许几个案例测试的是从不同角度去测试同一个功能(函数),这样你设置的断点可能经常被那些没有bug的案例干扰。这些问题都导致了不愉快的体验。那么怎么办呢?把其他案例都注释掉?也许一直以来你都这样去做了。可有更好的办法吗?

StdExt对CppUnit的改进

下面我们看看StdExt中是如何支持单元测试的。当然更重要的是,如何解决上面的这些问题的。

我曾经基于CppUnit写过一个增强版本的CppUnit。这个版本的CppUnit引入了两个概念(注意下面列了3条。第3条是写StdExt时引入的):

1、引入调试模式。

在调试模式下,CPPUNIT_ASSERT的行为与ASSERT/ATLASSERT一致,也是弹出断言对话框。而在普通模式下,则CPPUNIT_ASSERT报告案例执行错误,并不停下来。

2、引入案例执行的过滤条件。

也就是说,你可以选择只执行符合特定条件的案例。

3、把代码和针对该代码的测试案例写在同一个文件里。

写StdExt的时候,我为是否要把CppUnit引入到StdExt中,仔仔细细重新考察了下CppUnit。最终我决定,依据CppUnit的思想,写一个mini版本的CppUnit,而不直接基于CppUnit。

这是因为,StdExt的单元测试观念在CppUnit的测试理念之上,加了一条:

  • 把代码和针对该代码的测试案例写在同一个文件里。

这样做的好处是:

  • 你不容易忘记修改好代码后,去执行下相应的案例。
  • 你的代码规格改变后,你需要顺手修改一下测试案例的代码,以便它可以编译通过。
  • 测试案例一定程度上起到了示例代码的作用。

StdExt的单元测试样例

template <class LogT>
class TestFileBuf : public TestCase
{
public:
    WINX_TEST_SUITE(TestFileBuf);
        WINX_TEST(test);
    WINX_TEST_SUITE_END();
 
public:
    void test(LogT& log)
    {
        WinFileBuf file(__FILE__);
        log.printString(file.begin(), file.end());
 
        FILEFileBuf file2(__FILE__);
        AssertEq(file.size(), file2.size());
        AssertEqBuf(file.data(), file2.data(), file.size());
    }
};
 
void main()
{
    WINX_TEST_APP(std::ErrorLog, "TestFileBuf", "test");
    // this means to run the TestFileBuf::test function.
    // and, WINX_TEST_APP(std::ErrorLog, "", "") means to run all TestCases
 
    WINX_TEST_CLASS(TestFileBuf);
}

以上代码参见:

要下载完整的StdExt库,请到:

补充

本文第一次发表于我的CSDN博客:http://blog.csdn.net/xushiweizh/archive/2006/12/19/1449609.aspx ,当时StdExt仍然属于WINX的一部分。

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License

Subscription expired — please renew

Pro account upgrade has expired for this site and the site is now locked. If you are the master administrator for this site, please renew your subscription or delete your outstanding sites or stored files, so that your account fits in the free plan.