输出部分(Output)——基础部件


这一部分主要提供了一些用于输出测试结果的工具类,输出的方式可以有多种,比如:以纯文本方式输出,以XML标记语言方式输出,基于IDE开发环境的输出等。由此足见,CppUnit的实现者想得还是很周到的。

[Outputter]

相关文件:Outputter.h

这是一系列测试结果输出类的抽象基类,只有寥寥几行代码,唯一的作用是定义了一个write操作和一个virtual dtor:

virtual ~Outputter() {}
virtual void write() =0;

由于各种输出方式,其具体实现大相径庭,所以Outputter所能做的也止于此了。

[TestResultCollector]

相关文件:TestResultCollector.h,TestResultCollector.cpp

该类派生自TestSucessListener,同样也是TestListener和SynchronizedObject,因为前者派生自后二者。关于TestSucessListener请见listener部分,关于TestListener请见core部分。TestResultCollector的作用是搜集正在执行的测试用例的结果。依源码中的documentation comments所述,这是Collecting Parameter Pattern的一个应用[该Pattern在GoF中没有提及,morning有些孤陋寡闻]

TestSucessListene定义了三个成员变量,用来记录测试相关信息:

std::deque<Test *> m_tests;            // 指针队列用以记录测试对象
std::deque<TestFailure *> m_failures;  // 指针队列用以记录测试失败信息
int m_testErrors;                      // 用以记录测试错误个数

TestSucessListene还覆盖了基类TestListener的startTest,reset和addFailure方法:

void TestResultCollector::startTest( Test *test )
{
  ExclusiveZone zone (m_syncObject); 
  m_tests.push_back( test );               // 将测试对象加入链表中
}

void TestResultCollector::reset()
{
  TestSucessListener::reset();

  ExclusiveZone zone( m_syncObject ); 
  m_testErrors = 0;
  m_tests.clear();
  m_failures.clear();
}

void TestResultCollector::addFailure( const TestFailure &failure )
{
  TestSucessListener::addFailure( failure );

  ExclusiveZone zone( m_syncObject ); 
  if ( failure.isError() )                   // 若failure实为error,则m_testErrors加1
    ++m_testErrors;
  m_failures.push_back( failure.clone() );   // 此处用了clone
}

这里使用了ExclusiveZone,关于failure和error的差别,以及clone方法,请见core部分。由于使用了clone方法,所以在addFailure中创建的failure需要在dtor中回收:

TestResultCollector::~TestResultCollector()
{
  TestFailures::iterator itFailure = m_failures.begin();
  while ( itFailure != m_failures.end() )
    delete *itFailure++;
}

此外,就是几个getter方法了:

// 获取运行的测试个数
int TestResultCollector::runTests() const
{ 
  ExclusiveZone zone( m_syncObject ); 
  return m_tests.size(); 
}

// 获取运行错误的测试个数
int TestResultCollector::testErrors() const
{ 
  ExclusiveZone zone( m_syncObject );
  return m_testErrors;
}

// 获取运行失败的测试个数
int TestResultCollector::testFailures() const
{ 
  ExclusiveZone zone( m_syncObject ); 
  return m_failures.size() - m_testErrors;
}

// 获取运行错误及失败的测试的总个数
int TestResultCollector::testFailuresTotal() const
{
  ExclusiveZone zone( m_syncObject ); 
  return m_failures.size();
}

// 获取记录测试失败的链表
const TestResultCollector::TestFailures & 
TestResultCollector::failures() const
{ 
  ExclusiveZone zone( m_syncObject );
  return m_failures; 
}

// 获取记录测试对象的链表
const TestResultCollector::Tests &
TestResultCollector::tests() const
{
  ExclusiveZone zone( m_syncObject );
  return m_tests;
}

这里还想提一下有关TestResult和TestResultCollector的区别。根据随CppUnit所附的ChangeLog中的“记载”,早先版本的CppUnit中只有TestResult,它所实现的功能和TestResultCollector完全一样,像failures、testFailuresTotal等方法,原来都是在TestResult中的。不过在随后的refactoring过程中,由于引入了Observer Pattern,TestResultCollector应运而生,TestResult成了Subject,其原有记录测试运行结果的责任被移交给了TestResultCollector,而后者则是一个地道的Listener。于是原来在TestResult中出现的那些方法在Extract Method的“协助”之下被转移到了TestResultCollector中。

返回目录