📄 cppunit_cookbook中文版伟网动力.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0043)http://www.weiw.com/article/list.asp?id=458 -->
<!--include file="code.asp"--><HTML><HEAD><TITLE>CppUnit Cookbook中文版|伟网动力 http://www.weiw.com</TITLE>
<META content="MSHTML 6.00.2800.1400" name=GENERATOR>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META content=伟网动力,http://www.weiw.com name=keywords><LINK
href="CppUnit_Cookbook中文版伟网动力.files/style.css" rel=stylesheet>
<SCRIPT language=javascript1.2>
<!--
var currentpos,timer;
function initialize()
{
timer=setInterval('scrollwindow()',10);
}
function sc(){
clearInterval(timer);
}
function scrollwindow()
{
currentpos=document.body.scrollTop;
window.scroll(0,++currentpos);
if (currentpos != document.body.scrollTop)
sc();
}
document.onmousedown=sc
document.ondblclick=initialize
//-->
</SCRIPT>
</HEAD>
<BODY onmousemove="window.status='欢迎光临【伟网动力】http://www.weiw.com';">
<TABLE height=60 width="95%" align=center>
<TBODY>
<TR>
<TD width=200><A href="http://www.weiw.com/index.asp"><IMG
src="CppUnit_Cookbook中文版伟网动力.files/logo.gif" width=150 border=0
hight="50"></A> </TD>
<TD align=middle><!--
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0" width="468" height="60">
<param name=movie value="pic/aspsky.swf">
<param name=quality value=high>
<embed src="pic/aspsky.swf" quality=high pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="468" height="60">
</embed>
</object>
-->
<P><A href="http://www.weiw.com/article/list.asp?id=458#"><IMG height=55
src="CppUnit_Cookbook中文版伟网动力.files/ggzz.gif" width=346
border=0></A></P></TD></TR></TBODY></TABLE>
<SCRIPT language=JavaScript1.2>
if (document.all){
document.body.onselectstart =new Function("window.event.returnValue = false");
document.body.onmousedown=new Function("if (event.button==2||event.button==3) window.external.addFavorite('http://www.weiw.com','【伟网动力(weiw.com)】--专业网络技术站点')")
}
</SCRIPT>
<TABLE cellSpacing=0 cellPadding=0 width="98%" align=center border=0>
<TBODY>
<TR>
<TD>
<TABLE class=border cellSpacing=0 cellPadding=4 width="100%" border=0>
<TBODY>
<TR>
<TD class=title colSpan=2>| <A
href="http://www.weiw.com/article/default.asp?classid=2">.NET技术</A>
| <A
href="http://www.weiw.com/article/default.asp?classid=3">WEB开发</A> |
<A
href="http://www.weiw.com/article/default.asp?classid=4">JAVA技术</A>
| <A
href="http://www.weiw.com/article/default.asp?classid=5">应用程序</A> |
<A href="http://www.weiw.com/article/default.asp?classid=6">数据库</A>
| <A href="http://www.weiw.com/article/default.asp?classid=7"><FONT
color=red>软件工程</FONT></A> | <A
href="http://www.weiw.com/article/default.asp?classid=8">操作系统</A> |
<A href="http://www.weiw.com/article/default.asp?classid=9">网络管理</A>
| <A
href="http://www.weiw.com/article/default.asp?classid=10">IT认证与考试</A>
</TD></TR>
<TR>
<TD class=title2 colSpan=2>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width=*>| <A
href="http://www.weiw.com/article/index.asp?classid=7">软件工程</A>>><A
href="http://www.weiw.com/article/index.asp?classid=7&Nclassid=18">软件工程</A>>>CppUnit
Cookbook中文版 </TD>
<TD width=50><IMG
src="CppUnit_Cookbook中文版伟网动力.files/printpage.gif"
align=absMiddle> <A
href="http://www.weiw.com/article/printpage.asp?id=458">打印</A></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD class=tdbg colSpan=2>
<CENTER><B><FONT size=3>CppUnit
Cookbook中文版</FONT></B><BR>2003-6-30 伟网动力</CENTER>
<P>
<BLOCKQUOTE><BR><FONT
class=b1>这是我的第一份完整的翻译文章。欢迎大家指正,联系我:zgump@sina.com
<P></P>
<P>***************************************************************************</P>
<P><BR>本文是一篇简单的入门指导,帮助你快速上手。</P>
<P>简单测试用例(Simple Test Case)</P>
<P>你希望知道你的代码是否正在工作。<BR>你该怎么办?<BR>有很多种方法。使用调试器直接调试或者在你的代码里乱丢一些流输出指令是两种简单的方法,但是它们都有自己的缺点。直接调试代码是个好主意,但是它不是自动进行的。你不得不在每次改动代码以后重新调试。输出流文本也不错,但是它使代码变得面目可憎,并且大多数情况下,它输出的信息比你想要的要多。</P>
<P>在CppUnit中测试可以自动进行。这些测试可以很容易被建立,并且一旦你书写完毕,他们可以帮助你时刻了解你代码的质量。</P>
<P>为了做一个简单的测试,下面这些是你要做的:</P>
<P>从TestClass中派生一个类。Override runTest()方法。当你希望检查一个值的时候,调用
CPPUNIT_ASSERT(bool),如果测试成功这个assert表达式可以被顺利通过。</P>
<P>比如,为了测试一个复数类的等值比较,书写如下:</P>
<P>class ComplexNumberTest : public CppUnit::TestCase {
<BR>public: <BR>ComplexNumberTest( std::string name ) :
CppUnit::TestCase( name ) {}<BR><BR>void runTest()
{<BR>CPPUNIT_ASSERT( Complex (10, 1) == Complex (10, 1)
);<BR>CPPUNIT_ASSERT( !(Complex (1, 1) == Complex (2, 2))
);<BR>}<BR>};</P>
<P>这就是一个简单的测试。通常来说,你会有很多小的测试用例,并且希望能在同一个对象集合中测试。为了达到这个目的,使用fixture。</P>
<P>Fixture<BR>一个fixture是一组对象,被用来作为测试一组用例的基础。当你边开发边测试的时候,使用fixture会非常方便。</P>
<P>那我们尝试一下这种开发方式,同时学习一下fixture的使用方法。假定我们就是想开发一个复数的类,我们从定义一个名为Complex的空类开始。</P>
<P>class Complex{};</P>
<P>现在建立上面那个ComplexNumberTest测试用例,编译它们看看会发生什么。我们注意到的第一件事是有一些编译错误。测试使用了操作符==,但是它并没有被定义。修改如下:</P>
<P>bool operator==( const Complex & a, const Complex & b
)<BR>{<BR>return true;<BR>}</P>
<P>现在再次编译并运行之。这次编译通过了,但是没有通过测试。我们需要再写些代码使操作符==可以正确工作,所以我们再次修改代码:</P>
<P>class Complex { <BR>friend bool operator ==(const Complex&
a, const Complex& b);<BR>double real,
imaginary;<BR>public:<BR>Complex( double r, double i = 0 ) <BR>:
real(r)<BR>, imaginary(i) <BR>{<BR>}<BR>};</P>
<P>bool operator ==( const Complex &a, const Complex &b
)<BR>{ <BR>return eq( a.real, b.real ) && eq( a.imaginary,
b.imaginary ); <BR>}</P>
<P>如果我们现在编译并运行,就可以顺利通过测试。</P>
<P>现在我们准备添加一些新的操作符和新的测试用例。这时使用一个fixture会很方便。如果我们实例化3到4个复数并在测试中反复使用它们,可能我们的测试会更好些。<BR>我们这样做:<BR>*
为fixture的每个部分添加成员变量。<BR>* Override setUp() 初始化这些变量。<BR>* Override
tearDown()释放你在setUp()中使用的资源。</P>
<P>class ComplexNumberTest : public CppUnit::TestFixture
{<BR>private:<BR>Complex *m_10_1, *m_1_1,
*m_11_2;<BR>protected:<BR>void setUp()<BR>{<BR>m_10_1 = new
Complex( 10, 1 );<BR>m_1_1 = new Complex( 1, 1 );<BR>m_11_2 = new
Complex( 11, 2 ); <BR>}</P>
<P>void tearDown() <BR>{<BR>delete m_10_1;<BR>delete
m_1_1;<BR>delete m_11_2;<BR>}<BR>};</P>
<P>一旦我们拥有了这个fixture,我们就可以添加操作符+,以及整个开发过程中其他的任何操作符。</P>
<P>Test
Case<BR>为了使用一个fixture来调用单独的测试,该如何做呢?<BR>分为两个步骤:<BR>*以一个method的形式,在fixture类中写一个测试用例<BR>*创建TestCaller来运行那个method</P>
<P>这里是我们加了一些额外的用例method书写的测试类:<BR>private:<BR>Complex *m_10_1,
*m_1_1, *m_11_2;<BR>protected:<BR>void setUp()<BR>{<BR>m_10_1 =
new Complex( 10, 1 );<BR>m_1_1 = new Complex( 1, 1 );<BR>m_11_2 =
new Complex( 11, 2 ); <BR>}</P>
<P>void tearDown() <BR>{<BR>delete m_10_1;<BR>delete
m_1_1;<BR>delete m_11_2;<BR>}</P>
<P>void testEquality()<BR>{<BR>CPPUNIT_ASSERT( *m_10_1 == *m_10_1
);<BR>CPPUNIT_ASSERT( !(*m_10_1 == *m_11_2) );<BR>}</P>
<P>void testAddition()<BR>{<BR>CPPUNIT_ASSERT( *m_10_1 + *m_1_1 ==
*m_11_2 );<BR>}<BR>};</P>
<P>我们可以象下面这样为每个测试用例创建并运行一个实例:<BR>CppUnit::TestCaller<ComplexNumberTest>
test( "testEquality", <BR>&ComplexNumberTest::testEquality
);<BR>CppUnit::TestResult result;<BR>test.run( &result );</P>
<P>TestCaller的构造函数的第二个参数是ComplexNumberTest中对应method的地址。当这个TestCaller运行的时候,指定的method会运行。但是,这个办法也效果不彰,因为它不显示诊断信息。我们可以使用TestRunner(下面会讲到)来显示这个诊断信息。</P>
<P>一旦我们有了几个测试用例,可以把它们归入一个suite中。</P>
<P>Suite<BR>为了建立多个用例并且让它们一次全部运行,你该如何做呢?<BR>CppUnit提供了一个TestSuite类来同时运行任意个用例。<BR>在上面我们看到了如何运行一个测试用例。<BR>为了创建含有两个或更多用例的suite,你应该这么办:<BR>CppUnit::TestSuite
suite;<BR>CppUnit::TestResult result;<BR>suite.addTest( new
CppUnit::TestCaller<ComplexNumberTest>(<BR>"testEquality",
<BR>&ComplexNumberTest::testEquality ) );<BR>suite.addTest(
new
CppUnit::TestCaller<ComplexNumberTest>(<BR>"testAddition",
<BR>&ComplexNumberTest::testAddition ) );<BR>suite.run(
&result );</P>
<P>TestSuites不必仅仅含有测试用例的caller.它们可以包含实现Test
接口的任意对象。例如:你可以在你的代码中创建一个TestSuite,我也可以在我的代码里建立一个,我们通过建立一个同时包含它们两个的TestSuite使它们得以同时运行。<BR>CppUnit::TestSuite
suite;<BR>CppUnit::TestResult result;<BR>suite.addTest(
ComplexNumberTest::suite() );<BR>suite.addTest(
SurrealNumberTest::suite() );<BR>suite.run( &result );</P>
<P>TestRunner<BR>你该如何运行你的用例并收集测试结果呢?</P>
<P>一旦你有了一个TestSuite,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -