CPPUNIT实例
一、实例
在《CPPUNIT基本原理》中举了一个简单的例子,在这个实例的基础上,另外写了一个稍微复杂的例子用作cppunit的测试51Testing软件测试网3cy?V)P
这个实例包含一个Write2File cpp,一个Write2File h文件,功能是实现从一个文件复制内容到另一个文件。具体实现如下:
LA-V+cV5C)RP4B'c0Write2File.cpp的代码:51Testing软件测试网h3f|Y-z
#include "Write2File.h"51Testing软件测试网s\/['L"wom4| ?4~
Write2File::Write2File()
(z0[&I U2jO0{51Testing软件测试网5UA5Z)@ ZMY:j
}
;WQI0}#~0Write2File::~Write2File()
s|l1eq0{
&Pf^diE8J%dn0}51Testing软件测试网4H'Mqn~LJf(D%y
int Write2File::Process() //主过程51Testing软件测试网SD_*J{T
{51Testing软件测试网QW$Q)S d7j[,I
ReadCfgFile( );51Testing软件测试网4{L"D"fS H R
if( ReadFileSrc() )
;| pkX5K"z&?0{51Testing软件测试网5U2a.kI1G.v Y
return -1;51Testing软件测试网 _\0e-j9lL*B
}
0FUtK0Ve0if( WriteFileOut() )51Testing软件测试网.ha AB c!HL1a e#e
{51Testing软件测试网3NMQ5B ~6C
return -1;51Testing软件测试网SY%GA1m:S"{
}
,_B"z"h._0V0return 0;
lD nt.MU7U0}51Testing软件测试网 C$v2^6d/x} W@
int Write2File::ReadCfgFile() //这个函数本来是想实现从配置文件中获取输出目录和输出目录的,后来简化了这段代码,直接将路径赋值给变量了。51Testing软件测试网Yz.m o[(E5v W
{51Testing软件测试网q$K.W6H T3WQ0b2~
strcpy( SrcPath , m_srcp );
7bD'PW4Z0strcpy( OutPath , m_outp );
,C3R-u l){y.W.f051Testing软件测试网V6w&CFl+[ Xz
return 0;51Testing软件测试网GO0~ I3_"T-T ^
}
vA,sA*n6zCX_0int Write2File::ReadFileSrc() //读取源文件的内容51Testing软件测试网^Q4tO*_F
{
0Q+W3D)f w[&{0FILE *fp = NULL;
!p!f#Zg!w f0memset( SrcFilename , 0 ,sizeof( SrcFilename ) );
/Yt'@1m T[t!R0sprintf( SrcFilename , "%s/test_src.txt" , SrcPath );
s crhiQ4_"@0if( ( fp = fopen( SrcFilename , "r" ) ) == NULL )51Testing软件测试网Q#l)G"U5D b\?
{51Testing软件测试网)~{'EZC2~
printf( "Open srcfile error :%s\n" , SrcFilename );
nx+O ^Cr0[r9@E0return -1;
mN^C#Whg0}
L"i8Zj7a*Y,@0fnum = stat(SrcFilename,&statbuf);
;S0_nh(Q-u0if( fnum < 0 ) 51Testing软件测试网Iu#E1pg
{ 51Testing软件测试网d.L0Rv}
printf("there need size of file\n");
D6d ] A9?i0}51Testing软件测试网5xh/`JJr4q\t
51Testing软件测试网H\dT b5zw(c
fnum = statbuf.st_size; //源文件的大小51Testing软件测试网+~)H-Z7`^&Bi$W
fread( m_Buf , statbuf.st_size, 1 , fp );51Testing软件测试网D0dN:v;z)ob[
fclose( fp );
L&x%b0Lk2ntJZ0return 0;
&A(AE1J"Pb[0}
+YqD)ew0int Write2File::WriteFileOut() //将读取的内容输入到输出文件
1b`'R7SW0{51Testing软件测试网:cA:t*O!@8P.F'D
FILE *fp = NULL;51Testing软件测试网-i4O'G^ UZc
memset( OutFilename , 0 , sizeof(OutFilename ) );
)@#EM7{$[1RX0sprintf( OutFilename , "%s/test_out.txt", OutPath );51Testing软件测试网-dR p+keH
if( access(OutFilename , F_OK) == 0 ) unlink( OutFilename );51Testing软件测试网t,m3m B|@&P
if( ( fp = fopen(OutFilename , "a+") ) == NULL )
F!{%|awym0{51Testing软件测试网#Fo'AZ h!K;^
printf("Read file %s error!\n",OutFilename );
7Y5Am%mLV0return -1;51Testing软件测试网$KS0~"ZIMc w.w@3f
}51Testing软件测试网 scWir0H)K-~*EW
fwrite( m_Buf , statbuf.st_size , 1 , fp );
7ooA y1KN7D$V0fclose( fp );51Testing软件测试网4xt k3y:M,i
return 0;51Testing软件测试网GrHH ?;G @
}
Rf9h m$uRT0int main(int argc , const char **argv)
`b!rR4TF0{51Testing软件测试网-_E?5[#j zt1{
Write2File writefile;
Ud%v6a6{d(TWs0if( argc!=3 )
/C!r%F+Y7ZM;r'YW"s0{
0k!l8[.h)Z)ThE3v0printf( "ERROR,Example: Write2File srcpath outpath \n" );51Testing软件测试网)}+z4H/UG _%B
return -1;51Testing软件测试网jG#Qi zo9k,a
}51Testing软件测试网 T*mi;`z,W6WW t
m_argc = argc;
z_W+?)p)uH0strcpy( m_srcp , argv[1] );
;dg2Cv\O fq0strcpy( m_outp , argv[2] );51Testing软件测试网};G W)kSF.b&c@
//m_srcp = argv;
2OLIi5W:yo ] K]&d0writefile.Process();51Testing软件测试网fw/n D-h8`&rpi
return 0;51Testing软件测试网sAu]$v:@
}51Testing软件测试网N}QA'q1?
Write2File.h的代码:51Testing软件测试网6te R}\9Hi
#include <stdlib.h>51Testing软件测试网p&F/e:b*}c?'y
#include <math.h>
wIOH"j\g0#include <iostream.h>
+y4[P-L?M{4L#ut%~t0#include <unistd.h>
G~2}-G9T:M)_0#include <sys/stat.h>51Testing软件测试网I4X]zm3LI*]
#include <sstream>51Testing软件测试网'pJ,s!H8ADpV3qg
class Write2File51Testing软件测试网IRel8AmQ
{51Testing软件测试网[E*c5p&ak OK1un(v
public:
)x;LI}b"Z0Write2File();
T xNmb K{)cM0~Write2File();
0Q?Z+jo0public:
}6gxqt0char m_Buf[m_BufSize];51Testing软件测试网N g ? c4\2f8d)a&r%U
//protected:
`4YV RHA c R*r0int ReadCfgFile();
:ZdO Bx5A0int Process();51Testing软件测试网q0rm-~ca:Md#x3Q
int ReadFileSrc();
}$Q&]eY@0_0int WriteFileOut();
iQgvGLu1l0char SrcPath[256];51Testing软件测试网:k@PV(Gz"Y1r:u
char OutPath[256];51Testing软件测试网k6Eg@c;n2x
char SrcFilename[256];51Testing软件测试网PkFhoG
char OutFilename[256];51Testing软件测试网no/P2P*qi_
char Logfile[256];51Testing软件测试网"w sm{6B8K
char Logfilepath[256];
iX,?Fj D l0char Logfilename[256];51Testing软件测试网BAT5f,`
struct stat statbuf; 51Testing软件测试网t;h4U5}+[O2E
int fnum;
*P;\L+A f4b,c0};51Testing软件测试网-qZL e o? ler)F
int m_argc;
r{&`.Y1N0char m_srcp[256];
@!@G1}{0I(^0char m_outp[256];
:z&]V%qh!S/Nv0在cppunit的写的测试代码如下,其中包含main.cpp, testw2file.cpp, testw2file.h51Testing软件测试网p CcxdU
main.cpp的代码如下:——基本上,这个main.cpp不需要修改了,即使增加了测试用例也不需要修改这部分代码。
3?#~I/b4eX:Y [0#include "testw2file.h"51Testing软件测试网k ]+YGH
int main( )
m4m5U#bH'hz n0{
K5r8sM*R2ZrS0//CPPUNIT_TEST_SUITE_REGISTRATION(Test);
)Z/J:ZTi8D9n h0CPPUNIT_NS::TestResult controller;
DE E ?Z}0CPPUNIT_NS::TestResultCollector result;
n8G]eT0C_!gQ0controller.addListener(&result);
$M{B |O]0CPPUNIT_NS::BriefTestProgressListener progress;51Testing软件测试网k{/D-N9d&CzL
controller.addListener(&progress);51Testing软件测试网j5y;I)w0R{r
CPPUNIT_NS::TestRunner runner;
Dj nZH1q5f)^ ]0runner.addTest(CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest());
[ mWA4L6fUU0runner.run(controller);
cUg!@A2_0return result.wasSuccessful()?0:-1;
j8k/s[un0}51Testing软件测试网,x E?9kqRG
testw2file.h的代码如下:51Testing软件测试网*PM+Z4a8A,nM;q$}
#include "cppunit/Portability.h"51Testing软件测试网?xX?G WnN.]0L
#include "cppunit/TestAssert.h"
,t0T#na9N$`e_I?0#include "cppunit/extensions/TestFactoryRegistry.h"51Testing软件测试网-Y Y~ \;H
#include "cppunit/extensions/HelperMacros.h"
TE,P#r$p"Y}^c;m![F0#include "cppunit/TestResult.h"
[9qU6P,X2e!z:s0#include "cppunit/TestRunner.h"51Testing软件测试网 Z+GO-])r]
#include "cppunit/TestResultCollector.h"51Testing软件测试网/h*qw)Y$yg\'E
#include "cppunit/BriefTestProgressListener.h"
T1se|0Y#GNAVW8I0#include "Logger.h"
7j2k#r;MT&r!O0#include "/cxcs04/_hl/study/cppunit/testw2file/src/Write2File.cpp" //头文件把源代码文件包含进来,无须把被测试的源代码复制过来。
class W2File_Test:public CPPUNIT_NS::TestCase51Testing软件测试网v b*s/]6[Or%b
{
`{2N]rGI0CPPUNIT_TEST_SUITE(W2File_Test);
U/s N}u*o{0CPPUNIT_TEST(testw2file);
F-m[UCKQ6N0CPPUNIT_TEST_SUITE_END();51Testing软件测试网iY-D8M/a$O b{|
public:51Testing软件测试网 b,vpM v5fTx"J
void setUp(void);51Testing软件测试网7npS? C'|
void tearDown(void);
$q'YfX/Xz%X0char SrcPath[256];51Testing软件测试网] ^!t(p3Uo
protected:
;[ _tm XJ0int t_argc ;
~/MP#r4e0const char *t_argv[3];
:Tx'm iq ^ MkXQ0void testw2file(void);
4H7oa a4PEpV0int f_num;
b5X NO"yC ohU i0struct stat statbuf;
f'K7t.Sj4E,r8kx ^0};
L"V$|9a3Q/n.B:\t,^0CPPUNIT_TEST_SUITE_REGISTRATION(W2File_Test);
6r^s&uzD2`o0testw2file.cpp代码如下:51Testing软件测试网9a.~2V5pQ!f{$cZ
#include "testw2file.h"
/x0pJq I5^%w9n{l0void W2File_Test::setUp(void)
"r6Q?FXj3dj@0{51Testing软件测试网 @W-X`.M+{*d
t_argc = 3;
'M!F;h.H(q S @_:n;Z0t_argv[0]="1";
8V"M4U"c.p8J&U6hd'`@0t_argv[1]="/cxcs04/_hl/study/cppunit/testw2file/src";51Testing软件测试网k#OW9~@5?oZ\
t_argv[2]="/cxcs04/_hl/study/cppunit/testw2file/src";
r/E#P9xf)FKG PE!F4t0}51Testing软件测试网y6H3eN1l"e(~5T S_T
void W2File_Test::tearDown(void)
&j3c/EpUN!cP0{
N!x%[G;k051Testing软件测试网'p0F*} D?1cE
} 51Testing软件测试网a-s%j+l:Z#w
void W2File_Test::testw2file(void)51Testing软件测试网@%P,v#J3Q:N
{
6Rg8z;TO!B F0int i;
N uz;I'A#?6Z0FILE *fp_out=NULL;
/q _EC*Q0Write2File W2file;51Testing软件测试网x&~ g\a3V I:Pe ` H
char t_outfile[256];51Testing软件测试网Ar$?QjwB
sprintf( t_outfile , "%s/test_out.txt" , t_argv[1] );51Testing软件测试网EJ2M"M J8Tgs
W2file.ReadCfgFile(t_argc , t_argv );
+L*`7]1v9ML(Y5?0fp_out = fopen(t_outfile , "r");51Testing软件测试网X6XV;w6QNMe
stat( t_outfile , &statbuf );
?Z:y,i9B%H0f_num = statbuf.st_size;//测试代码获取输出文件的真实大小
.[Dt:p&|;XS`-k+hs]0 printf( "outfile size =%d , srcfile size =%d\n" , f_num , W2file.fnum ); //将代码中获取的输出文件的真实大小和源代码中源文件的大小作对比(即预期值)
CPPUNIT_ASSERT( f_num == W2file.fnum ); //判断两个值的大小,如果一致这个用例就是成功的。
}
K7H!NV3LO#@0如果是在unix环境下,可以写makefile文件完成程序的编译,在此顺便把我的makefile文件也贴出来:
]~%XIX?[kL!Y0CPP =g++ -g51Testing软件测试网T/w5J;V7I3a%R e
INCL = -I/mylib/include
RMiY7Re*B9e$}&_0LIBS =-L/mylib/lib -lcppunit51Testing软件测试网/} ?T(Os
SYSLIB = -ldl
IO!zPMSui~pa0PROGRAMS = testw2file
RRJ`7oFx0OBJS =main.o testw2file.o51Testing软件测试网1S6\RT wg@9s
testw2file:${OBJS}
u8Z@3y_ v)G!hM%Q3o:U%`0$(CPP) $(CPPFLAG) -o $@ ${OBJS} $(LIBS) ${SYSLIB} ${INCL}
8[z j!K&p)r\\0clean:
wb!c0@c.\!u,_0rm *.o testw2file51Testing软件测试网hE_4\ `b:v^2y9fA
二、总结
在网上有不少CPPUNIT的资料,不知道最初的出处在哪里,有一些看了也不是特别清楚要怎么去使用cppunit,实例也不一定就能真正运行起来(当然这份资料也是借鉴了很多网上同行的资料)。为了让入门者更容易上手,在这里班门弄匠地总结一下自己接触CPPUNIT的心得,上面也附了一两个实例,仅是互相学习的意思。
X!B`Q*w\01 CPPUNIT其实是相当于一个框架,我们设计好了测试的方法、预期值后,将源代码放到这个框架中去执行,以检查源代码的输出是否跟预期值是相符的。51Testing软件测试网,S(n#cg0XZ4^
2不需要将源代码贴到测试代码中去,一般建议保持源代码和测试代码的独立性51Testing软件测试网 LYt E1v a}
3对于预期值需要根据源代码的实际情况去设置,比如如果我要判断一个复制文件的函数执行是否成功,可能先要在测试代码中实现获取复制文件的大小,再将这个大小和源文件进行对比,如果一致,说明这个函数执行是成功的。因此,如何判断某个函数的执行是否成功,这个预期值应该取什么值以及要如何获得这个预期值,都是需要思考的,而且在测试代码中的实现有可能也会比较复杂。不过只要一次实现后,以后的修改就比较小了。51Testing软件测试网*h*NI*K G%Q%\
4对于有桩函数或者是驱动函数的函数,需要在测试代码中实现先将被测源代码中实现桩函数或驱动函数的功能。比如被测函数需要用到一个变量,则需要在测试代码中先给这个变量赋值,或者是被测函数需要桩函数先实现某个功能或达到某个条件,则需要在测试代码中先将这个前提条件满足。
+d!K` ~|l(e05如果涉及数据库的代码,建议是不要用CPPUNIT来实现,其实直接用功能测试来检查结果会更快捷.
"P5f3M7^E0'Y&y5Y?M-`3~1t-hU0
__原创文章,欢迎探讨
:r!\} On.A9^Q B0TAG:
- 引用 删除 xiaoler / 2010-08-23 16:24:53
- CppUnit提供一个单元测试测试框架,基本能满足单元测试的需求,但仍然存在一些弊端,建议看看C++test专业测试博客上面的一些论述:www.mytestlife.com
- 引用 删除 ken867 / 2008-11-25 10:34:30
- CPPUNIT,测试框架,挺好用的一个工具,相对于其他的测试工具来说似乎相对比较复杂,楼主写得很好,对不知道怎么做的测试开发工程师是一个很好的提高
- 引用 删除 define_NULL / 2008-10-30 11:45:27
-
楼主写得不错。不过我有几点疑问!
1。 首先我觉得在测试Process(0之前,没有对ReadFileSrc() 和WriteFile Src()做测试,这样子。可行吗?万一出错在这中间,怎么定位!
2. 看你写的测试,直接是改掉了被测类属性域属性,那样的话,测试都应该按照那样去改?
3. 对于面向对象的单元测试,确实很迷糊,如有的函数没有参数,直接对类属性的修改,这个该怎么测?(只是针对这个修改API而言)