分享
 
 
 

CppUnit源码解读(6)

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

【声明】如需复制、传播,请附上本声明,谢谢。原文出处:http://morningspace.51.net/,moyingzz@etang.com

扩展部分(Extension)

在CppUnit中,除了提供基本的单元测试之外,还增加了很多扩展测试,比如:重复测试(RepeatedTest),正规测试(OrthodoxTest),这些内容都悉数收录在extension中。

[TestDecorator] 相关文件:TestDecorator.h 它提供了一种方法,可以不用子类化Test类,同时又能扩展Test类的功能。我们可以派生TestDecorator,并用它来包装Test。其实这种方法是Decorator Pattern的一个应用,在GoF中对该pattern有如下描述:动态地给一个对象添加一些额外的职责。就增加功能来说,比生成子类更为灵活。 TestDecorator维护了一个指向Test实例的指针,并在ctor中设定。不过该实例的生命期,TestDecorator并不过问: protected: Test *m_test;随后是四个public函数,其接口与Test的接口完全一致: void run (TestResult *result);int countTestCases () const;std::string getName () const;std::string toString () const;函数的实现就是简单的调用m_test的对应接口: inline int TestDecorator::countTestCases () const{ return m_test->countTestCases (); }inline void TestDecorator::run (TestResult *result){ m_test->run (result); }inline std::string TestDecorator::toString () const{ return m_test->toString (); }inline std::string TestDecorator::getName () const{ return m_test->getName(); }在TestDecorator的派生类中,这些功能将得到扩展。 [RepeatedTest] 相关文件:RepeatedTest.h,RepeatedTest.cpp 派生自TestDecorator,其功能是对测试重复运行指定的次数(类似于某种强度测试)。private成员变量m_timesRepeat记录了重复的次数: private: const int m_timesRepeat;该值在ctor中设定: RepeatedTest( Test *test,int timesRepeat ) : TestDecorator( test ), m_timesRepeat(timesRepeat) {}这里的test参数,就是所要执行的测试,可能是某个测试用例,也可能是测试包。 随后是函数countTestCases、run和toString的子类化版本: // 返回本次测试中测试用例的总数// 总数 = 实际总数 * 重复次数int RepeatedTest::countTestCases() const{ return TestDecorator::countTestCases () * m_timesRepeat;}std::string RepeatedTest::toString() const{ return TestDecorator::toString () + " (repeated)";}// 运行测试// 重复调用基类的run,并在基类中调用m_test的run方法void RepeatedTest::run( TestResult *result ){ for ( int n = 0; n < m_timesRepeat; n++ ) { if ( result->shouldStop() ) break; TestDecorator::run( result ); }}[Orthodox] 相关文件:Orthodox.h 该类实现了正规测试的功能。它派生自TestCase,是一个模板类,有一个类型参数ClassUnderTest,代表将要运行的测试。所谓正规测试,就是对待测类(即ClassUnderTest)执行一组简单的测试,确保其至少具有如下基本操作: default ctor operator==和operator!= assignment(即operator=) operator! safe passage(即copy ctor) 若其中任何一项没有通过测试,则模板类就不会实例化。否则,实例化后将检查这些操作的语义是否正确。当你需要确认一组待测类具有相同表现时,采用被模板化的测试用例非常有用,Orthodox就是一个很好的例子。可以想见,在实际工作中,我们也可以效仿Orthodox的做法,从而“扩展”CppUnit以适应自己的特定环境。 以下代码演示了如何将一个复数类的正规测试添加到测试包中: TestSuite *suiteOfTests = new TestSuite;suiteOfTests->addTest (new ComplexNumberTest ("testAdd");suiteOfTests->addTest (new TestCaller<Orthodox<Complex> > ()); // 非常简单来看一下Orthodox的定义: template <typename ClassUnderTest> class Orthodox : public TestCase{public: Orthodox () : TestCase ("Orthodox") {}protected: ClassUnderTest call (ClassUnderTest object); void runTest ();};唯一需要解释的就是runTest方法,Orthodox是如何检查ClassUnderTest是否符合要求的呢: template <typename ClassUnderTest>void Orthodox<ClassUnderTest>::runTest (){ // 确保default ctor被定义,否则无法通过编译 ClassUnderTest a, b, c; // 确保operator==被定义,否则无法通过编译 // 同时检查operator==的语义 CPPUNIT_ASSERT (a == b); // 确保operator!、operator=和operator!=被定义 // 否则无法通过编译 // 同时检查operator!=的语义 b.operator= (a.operator! ()); CPPUNIT_ASSERT (a != b); // 检查operator!和operator==的语义 b = !!a; CPPUNIT_ASSERT (a == b); b = !a; // 以下检查copy ctor是否被定义及其语义正确与否 c = a; CPPUNIT_ASSERT (c == call (a)); c = b; CPPUNIT_ASSERT (c == call (b));}这里的call是辅助函数,“迫使”编译器调用copy ctor,以检查safe passage: template <typename ClassUnderTest>ClassUnderTest Orthodox<ClassUnderTest>::call (ClassUnderTest object){ return object;}所有的奥妙就在上面这几行代码中。 [TestSetUp] 相关文件:TestSetUp.h,TestSetUp.cpp 同样派生自TestDecorator,它使测试类具有了SetUp和TearDown的特性。关于这两个特性请见core部分的TestFixture。 该类定义了两个protected属性的虚函数,以供派生类覆盖: protected: virtual void setUp(); virtual void tearDown();此外,就是子类化了run方法: void TestSetUp::run( TestResult *result ){ setUp(); TestDecorator::run(result); tearDown();}

[后记]

正如我在“CppUnit源码解读(1)”一文中所说,这一系列的文章是从《CppUnit源码解读》中摘选出来的,并且我认为是主要部分的章节。 我打算将本文做为这一系列文章的结尾,不过,对此仍感兴趣的朋友将可以在我的主页上找到这一系列文章的完整版本:http://morningspace.51.net/resource/cppunit/cppunit_anno.html

当然,所谓主要也只是个人的主观划分。比如CppUnit中另一个重要环节——结果输出,这里就没有提到,那是Observer Pattern的用武之地。另外,CppUnit的类厂实现机制也是很有特色的。就这些议题,你将可以在完整版中找到。

这么做,是出于如下的考虑:文章的内容毕竟出于源码的个人阅读笔记(最初是写给自己看的:),并且由于时间关系,我也无法将其做得十分精致(比如就像有人抱怨的没有画上图示,类图等等:)。看久了难免让人觉得有点像记流水帐,让人觉得乏味。与其如此,到不如让那些不介意流水账的朋友来网站看后续内容,而介意者也就无需再继续看下去了:)

再次重申,本文系源码笔记,如果你想了解有关CppUnit的使用,请参考其他文献,据我所知CSDN的文档中心里就有一篇入门性的文章:)

—— Morning

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有