cxxtest单元测试框架源码分析(二):所有对外功能实现分析

    CxxTest的大部分诊断功能都是通过宏定义实现的,而且这部分的定义以及所有测试套的基类CxxTest:TestSuite定义和实现都在TestSuite.h和TestSuite.cpp里面。下面我们将通过分析这两个文件来分析CxxTest的对外功能体现。

  1  // 所有的类以及定义都是在CxxTest名称空间中
  2  namespace  CxxTest  
  3  {
  4       // 下面是测试套的定义,三个虚函数;在TestSuite.cpp中有实现,不过在你写的测试套中可以重载它
  5       class  TestSuite  
  6      {
  7       public :
  8           virtual   ~ TestSuite();
  9           virtual   void  setUp();     // 在该测试套的每个用例的执行之前运行,可以用于建立初始环境
 10           virtual   void  tearDown();  // 在该测试套的每个用例的执行之后运行,可以用于恢复初始环境
 11      };
 12      
 13       class  AbortTest {};          // 用于抛出测试终止异常,在定义了_CXXTEST_HAVE_EH时有效
 14       void  doAbortTest();
 15  #   define TS_ABORT() CxxTest::doAbortTest()
 16      
 17       // 下面这两个接口分别用于控制当诊断失败时,是否继续运行,默认为继续运行
 18       bool  abortTestOnFail();
 19       void  setAbortTestOnFail(  bool  value  =  CXXTEST_DEFAULT_ABORT );
 20 
 21       // 下面两个接口用于设置最大Dump的大小
 22      unsigned maxDumpSize();
 23       void  setMaxDumpSize( unsigned value  =  CXXTEST_MAX_DUMP_SIZE );
 24 
 25       // 下面的接口对应到TS_TRACE,用于跟踪信息
 26       void  doTrace(  const   char   * file, unsigned line,  const   char   * message );
 27 
 28       // 下面的接口对应到TS_WARN,用于打印to-do list
 29       void  doWarn(  const   char   * file, unsigned line,  const   char   * message );
 30 
 31       // 下面的接口对应TS_FAIL宏,直接诊断失败
 32       void  doFailTest(  const   char   * file, unsigned line,  const   char   * message );
 33 
 34       // 下面的接口对应TS_ASSERT宏,直接表达式是否为真
 35       void  doFailAssert(  const   char   * file, unsigned line,  const   char   * expression,  const   char   * message );
 36      
 37       // 下面的接口对应TS_ASSERT_EQUALS宏,用于判断两个值是否相等。因为涉及不同的基本类型,所以这里定义是函数模板
 38      template < class  X,  class  Y >
 39       bool  equals( X x, Y y )
 40      {
 41           return  (x  ==  y);
 42      }
 43 
 44      template < class  X,  class  Y >
 45       void  doAssertEquals(  const   char   * file, unsigned line,
 46                            const   char   * xExpr, X x,
 47                            const   char   * yExpr, Y y,
 48                            const   char   * message )
 49      {
 50           if  (  ! equals( x, y ) ) {
 51               if  ( message )
 52                  tracker().failedTest( file, line, message );
 53              tracker().failedAssertEquals( file, line, xExpr, yExpr, TS_AS_STRING(x), TS_AS_STRING(y) );
 54              TS_ABORT();
 55          }
 56      }
 57 
 58       // 下面的接口对应TS_ASSERT_SAME_DATA宏,用于判断给定大小的两段数据是否相等。
 59       void  doAssertSameData(  const   char   * file, unsigned line,
 60                              const   char   * xExpr,  const   void   * x,
 61                              const   char   * yExpr,  const   void   * y,
 62                              const   char   * sizeExpr, unsigned size,
 63                              const   char   * message );
 64 
 65        // 下面的接口对应TS_ASSERT_DIFFERS宏,用于诊断两个值不相等,同样定义为函数模板。
 66      template < class  X,  class  Y >
 67       bool  differs( X x, Y y )
 68      {
 69           return   ! (x  ==  y);
 70      }
 71 
 72      template < class  X,  class  Y >
 73       void  doAssertDiffers(  const   char   * file, unsigned line,
 74                             const   char   * xExpr, X x,
 75                             const   char   * yExpr, Y y,
 76                             const   char   * message )
 77      {
 78           if  (  ! differs( x, y ) ) {
 79               if  ( message )
 80                  tracker().failedTest( file, line, message );
 81              tracker().failedAssertDiffers( file, line, xExpr, yExpr, TS_AS_STRING(x) );
 82              TS_ABORT();
 83          }
 84      }
 85 
 86       // 下面的接口对应TS_ASSERT_LESS_THAN宏,用于诊断两个值是否为满足<,同样定义为函数模板。
 87      template < class  X,  class  Y >
 88       bool  lessThan( X x, Y y )
 89      {
 90           return  (x  <  y);
 91      }
 92 
 93      template < class  X,  class  Y >
 94       void  doAssertLessThan(  const   char   * file, unsigned line,
 95                              const   char   * xExpr, X x,
 96                              const   char   * yExpr, Y y,
 97                              const   char   * message )
 98      {
 99           if  (  ! lessThan(x, y) ) {
100               if  ( message )
101                  tracker().failedTest( file, line, message );
102              tracker().failedAssertLessThan( file, line, xExpr, yExpr, TS_AS_STRING(x), TS_AS_STRING(y) );
103              TS_ABORT();
104          }
105      }
106 
107      // 下面的接口对应TS_ASSERT_LESS_THAN_EQUALS宏,用于诊断两个值是否为满足<=,同样定义为函数模板。
108      template < class  X,  class  Y >
109       bool  lessThanEquals( X x, Y y )
110      {
111           return  (x  <=  y);
112      }
113 
114      template < class  X,  class  Y >
115       void  doAssertLessThanEquals(  const   char   * file, unsigned line,
116                                    const   char   * xExpr, X x,
117                                    const   char   * yExpr, Y y,
118                                    const   char   * message )
119      {
120           if  (  ! lessThanEquals( x, y ) ) {
121               if  ( message )
122                  tracker().failedTest( file, line, message );
123              tracker().failedAssertLessThanEquals( file, line, xExpr, yExpr, TS_AS_STRING(x), TS_AS_STRING(y) );
124              TS_ABORT();
125          }
126      }
127 
128      // 下面的接口对应TS_ASSERT_PREDICATE宏,用于诊断P(x)表达式,同样定义为函数模板。
129      template < class  X,  class  P >
130       void  doAssertPredicate(  const   char   * file, unsigned line,
131                               const   char   * pExpr,  const  P  & p,
132                               const   char   * xExpr, X x,
133                               const   char   * message )
134      {
135           if  (  ! p( x ) ) {
136               if  ( message )
137                  tracker().failedTest( file, line, message );
138              tracker().failedAssertPredicate( file, line, pExpr, xExpr, TS_AS_STRING(x) );
139              TS_ABORT();
140          }
141      }
142 
143      // 下面的接口对应TS_ASSERT_RELATION宏,用于诊断R(x,y)表达式,同样定义为函数模板。
144      template < class  X,  class  Y,  class  R >
145       void  doAssertRelation(  const   char   * file, unsigned line,
146                              const   char   * rExpr,  const  R  & r, 
147                              const   char   * xExpr, X x,
148                              const   char   * yExpr, Y y,
149                              const   char   * message )
150      {
151           if  (  ! r( x, y ) ) {
152               if  ( message )
153                  tracker().failedTest( file, line, message );
154              tracker().failedAssertRelation( file, line, rExpr, xExpr, yExpr, TS_AS_STRING(x), TS_AS_STRING(y) );
155              TS_ABORT();
156          }
157      }
158 
159      // 下面的接口对应TS_ASSERT_DELTA宏,用于诊断(y >= x - d) && (y <= x + d)表达式,同样定义为函数模板。
160      template < class  X,  class  Y,  class  D >
161       bool  delta( X x, Y y, D d )
162      {
163           return  ((y  >=  x  -  d)  &&  (y  <=  x  +  d));
164      }
165 
166      template < class  X,  class  Y,  class  D >
167       void  doAssertDelta(  const   char   * file, unsigned line,
168                           const   char   * xExpr, X x,
169                           const   char   * yExpr, Y y,
170                           const   char   * dExpr, D d,
171                           const   char   * message )
172      {
173           if  (  ! delta( x, y, d ) ) {
174               if  ( message )
175                  tracker().failedTest( file, line, message );
176              
177              tracker().failedAssertDelta( file, line, xExpr, yExpr, dExpr,
178                                           TS_AS_STRING(x), TS_AS_STRING(y), TS_AS_STRING(d) );
179              TS_ABORT();
180          }
181      }
182 
183      // 下面的接口对应除TS_ASSERT_THROWS_NOTHING宏以外的所有对外异常宏诊断。
184       void  doFailAssertThrows(  const   char   * file, unsigned line,
185                                const   char   * expr,  const   char   * type,
186                                bool  otherThrown,
187                                const   char   * message );
188      
189      // 下面的接口对应TS_ASSERT_THROWS_NOTHING宏,用于诊断没有抛出任何异常。
190       void  doFailAssertThrowsNot(  const   char   * file, unsigned line,
191                                   const   char   * expression,  const   char   * message );
192 
193      // 下面的接口对应TS_ASSERT_SAME_FILES宏,用于诊断两个文件是否相等(这个功能还没有发布)。
194       void  doAssertSameFiles(  const   char *  file, unsigned line,
195                               const   char *  file1,  const   char *  file2,
196                               const   char *  message);
197 
198      // 下面这里定义了两组异常相关的宏,如果没有定义_CXXTEST_HAVE_EH,则全部为空
199  #   ifdef _CXXTEST_HAVE_EH
200  #       define _TS_TRY  try
201  #       define _TS_CATCH_TYPE(t, b)  catch  t b
202  #       define _TS_CATCH_ABORT(b) _TS_CATCH_TYPE( ( const  CxxTest::AbortTest  & ), b )
203  #       define _TS_LAST_CATCH(b) _TS_CATCH_TYPE( (), b )
204  #       define _TSM_LAST_CATCH(f,l,m) _TS_LAST_CATCH( { (CxxTest::tracker()).failedTest(f,l,m); } )
205           // 下面根据是否定义了使用标准库宏,来决定是否加入std::exception异常的捕获处理
206  #       ifdef _CXXTEST_HAVE_STD
207  #           define ___TSM_CATCH(f,l,m) \
208                       catch ( const  std::exception  & e) { (CxxTest::tracker()).failedTest(f,l,e.what()); } \
209                      _TSM_LAST_CATCH(f,l,m)
210  #        else   //  !_CXXTEST_HAVE_STD
211  #           define ___TSM_CATCH(f,l,m) _TSM_LAST_CATCH(f,l,m)
212  #       endif  //  _CXXTEST_HAVE_STD
213  #       define __TSM_CATCH(f,l,m) \
214                  _TS_CATCH_ABORT( {  throw ; } ) \
215                  ___TSM_CATCH(f,l,m)
216  #       define __TS_CATCH(f,l) __TSM_CATCH(f,l, " Unhandled exception " )
217  #       define _TS_CATCH __TS_CATCH(__FILE__,__LINE__)
218  #    else   //  !_CXXTEST_HAVE_EH
219  #       define _TS_TRY
220  #       define ___TSM_CATCH(f,l,m)
221  #       define __TSM_CATCH(f,l,m)
222  #       define __TS_CATCH(f,l)
223  #       define _TS_CATCH
224  #       define _TS_CATCH_TYPE(t, b)
225  #       define _TS_LAST_CATCH(b)
226  #       define _TS_CATCH_ABORT(b)
227  #   endif  //  _CXXTEST_HAVE_EH
228 
229       // 下面就是所有对外的诊断宏定义,对于基本的诊断包含了四类:
230       // 1、标准的诊断 TS_ASSERT_XXX形式命名,如:TS_ASSERT(e)
231       // 2、定义自己异常处理诊断 ETS_ASSERT_XXX形式命名,如:ETS_ASSERT(e) 
232       // 3、带了消息的打印的诊断 TSM_ASSERT_XXX形式命名,如:TSM_ASSERT(m,e)
233       // 4、既自己处理异常又带有消息的诊断 ETSM_ASSERT_XXX形式命名,如:ETSM_ASSERT(m,e)
234 
235       //  TS_TRACE
236  #   define _TS_TRACE(f,l,e) CxxTest::doTrace( (f), (l), TS_AS_STRING(e) )
237  #   define TS_TRACE(e) _TS_TRACE( __FILE__, __LINE__, e )
238 
239       //  TS_WARN
240  #   define _TS_WARN(f,l,e) CxxTest::doWarn( (f), (l), TS_AS_STRING(e) )
241  #   define TS_WARN(e) _TS_WARN( __FILE__, __LINE__, e )
242 
243      。。。。这部分都是对外宏定义,这里省略,大家一看应该就明白
244   

245 } 

在TestSuite.cpp主要实现了在TestSuite.h中定义的非模板函数,都比较简单,所有这里就不再解析了。这里主要分析一个函数,关于诊断失败时是否退出的处理函数, 

1       void  doAbortTest() // 实现在诊断失败时是否停止该用例的执行
2      {
3         // 从这里可以看出_CXXTEST_HAVE_EH和CXXTEST_ABORT_TEST_ON_FAIL为什么要一起使用了吧
4         #if   defined(_CXXTEST_HAVE_EH)
5            if  ( currentAbortTestOnFail )
6                 throw  AbortTest();
7         #endif   //  _CXXTEST_HAVE_EH9    

8     }

OK,本文就分析到这里。

(PS:今天发这个帖子写了两遍,第一次刚写完Google浏览器就挂了,晕倒!!!!) 

版权说明

转载改文章请指明出处http://www.cnblogs.com/xiaocheng,多谢!

Author: Elvis.Chen 

你可能感兴趣的:(单元测试)