单元测试作业指导书(一)

原创 2003年11月09日 23:02:00

这是我以前任项目经理时,编写的关于单元测试方面的作业指导书,针对多种开发环境叙述怎么进行单元测试以及环境配置,现在整理了一下。应该对大家有所帮助。

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

 这是第一部分,主要针对C和C++项目的(包括了Windows环境和Linux环境),下部分将针对Java及J2EE项目。

 

1.      目的

为了减少代码中的错误数量, 减少调试所花的时间和精力, 改善软件质量, 减少开发和维护的时间和成本 

  

2.      适用范围

适用于C及C++的所有产品。

 

3.      适用内容

<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />3.1  C++标准

3.1.1测试环境使用Visual C++Windows窗口应用程序

3.1.1.1前题:使用CppUnit1.6.2版,解压后,路径为x://cppunit-1.6.2

在工程文件中配置测试框架使用环境:加入执行头文件的路径x://cppunit-1.6.2/include,加入导入库文件的路径x://cppunit-1.6.2/lib

配置DEBUG(测试)版环境:

加入需要链接的静态测试框模块testrunnercd.lib(运行测试用例的选择对话框)和cppunitcd.lib(测试框架);

加入测试Add-ins,库名为x://cppunit-1.6.2/lib/TestRunnerDSPlugInD.dll

Project Settings/C++/C++ Language中启用RTTI

 

3.1.1.2建立测试用例:

1、以类名加前辍“Test”命名测试单元文件名,比如“CMabString”类的类文件名为MabString.cpp,则测试单元文件命名为TestMabString.cpp

2、加入测试框架头文件以及要测试的单元头文件,以TestMabString为例:

头文件:testmabstring.h

 

#ifndef CPP_UNIT_TestNode_H

#define CPP_UNIT_TestNode_H

//包含测试框架的头文件

#include <cppunit/TestCase.h>

#include <cppunit/extensions/HelperMacros.h>

//包含被测试单元的头文件

#include "mabstring.h"

//派生测试框架的测试用例类

class TestMabString : public CppUnit::TestCase

{

  //定义测试用例列表,此列表将出现在运行测试用例的选择对话框中

  CPPUNIT_TEST_SUITE( TestMabString );

  CPPUNIT_TEST( FindByName );

  CPPUNIT_TEST_SUITE_END();

 

protected:

       //

       CMabString  m_MabStr;

public:

       //用例初始化,可作为桩函数

       void setUp ();

       //用例析构

       void tearDown();

 

protected:

       //测试用例

       void FindByName (void);

};

 

#endif

 

类文件:testmabstring.cpp

 

#include "TestMabString.h"

#include "iostream.h"

#include "strstrea.h"

 

//注册本测试单元

CPPUNIT_TEST_SUITE_REGISTRATION( TestMabString );

//定义测试用例

void TestMabString::FindByName ()

{

       //功能性测试,属黑盒测试

       //normal test         

      

       //条件及错误测试,属白盒测试

       //extra test,

 

       //例外测试,属白盒测试

       //exception test,

       bool bRet=false;

       try{

              //put the exception code here...

       }

       //catch(CXXX& e)

       catch(...)

       {           

              bRet=true;

       }

       CPPUNIT_ASSERT(bRet);

      

//由于并不能够执行所有单元测试应该执行的路径,比如CMabString是从CString

//类中派生出来的,而可能CMabString中的Find只简单调用了CString中的Find方法,//所以并不需要测试;

//在此处说明所有不用测试的路径;

//other test, see the ...

}

 

void TestMabString::setUp ()

{

       //开始测试前的初始代码

       m_pNode=new Node();

}

 

void TestMabString::tearDown()

{

       //测试结束代码

       if(m_pNode)

              delete m_pNode;

}

 

3、在启动程序中加入以下代码,以便运行“测试用例选择”对话框:

#ifdef _DEBUG

//包括测试头文件

#include <msvc6/testrunner/TestRunner.h>

#include <cppunit/extensions/TestFactoryRegistry.h>

static AFX_EXTENSION_MODULE  extTestRunner;

#endif

 

       //以下为测试代码,此部分测试不会出现在发布版中

#ifdef _DEBUG

       TestRunner  runner;

    runner.addTest ( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );

    runner.run ();

#endif

 

4、制作发行版

发行版需要做以下工作:

Project的属性设置为Release(这将自动去除_DEBUG的声明);

从工程项目中去掉测试文件(即带有test前辍的文件);

 

3.1.2测试环境使用Visual C++Windows非窗口应用程序

3.1.2.1前题:使用CppUnit1.6.2版,解压后,路径为x://cppunit-1.6.2

在工程文件中配置测试框架使用环境:加入执行头文件的路径x://cppunit-1.6.2/include,加入导入库文件的路径x://cppunit-1.6.2/lib

配置DEBUG(测试)版环境:

加入需要链接的静态测试框模块cppunitcd.lib(测试框架);

Project Settings/C++/C++ Language中启用RTTI

 

3.1.2.2建立测试用例:

1、以类名加前辍“Test”命名测试单元文件名,比如“CMabString”类的类文件名为MabString.cpp,则测试单元文件命名为TestMabString.cpp

2、加入测试框架头文件以及要测试的单元头文件,以TestMabString为例:

头文件:testmabstring.h

3、测试示例同上;

 

3.2  C标准

3.2.1测试环境使用gccLinux非窗口应用程序

前题:使用check0.8.0版,解压后,路径为/xx/check-0.8.0

配置测试框架使用环境(我建议采用标准组织推荐的使用AutoconfAutomake来生成配置文件configureMakefile,因为使用它们可以建立符合国际标准的configure脚本 Makefile文件,并且可以有效的建立压缩包和方便分发必需的文件(也方便在发行版中去除测试用例文件)

l         首先需编写configure.in文件,此文件用于Autoconf生成configure可执行脚本;configure.in的框架大致如下:

dnl 此文件用于生成configure脚本,

dnl AC_INITxxxx.h参数代表本目录下一个有效的文件名

AC_INIT(xxxx.h)

dnl AM_INIT_AUTOMAKE的两个参数分别是生成应用程序的版本及版本号,

dnl 可能有些版本的AutoconfAutomake不支持此宏

AM_INIT_AUTOMAKE(xxxx, x.x)

dnl 以下为编译依赖的检测

dnl Checks for programs.

AC_PROG_AWK

AC_PROG_CC

AC_PROG_INSTALL

AC_PROG_LN_S

 

dnl Checks for libraries.

AC_CHECK_LIB(check,suite_create)

 

dnl Checks for header files.

AM_CONFIG_HEADER(config.h)

 

dnl Checks for typedefs, structures, and compiler characteristics.

 

dnl Checks for library functions.

 

dnl Automake生成的Makefile.in文件输出为Makefile文件

AC_OUTPUT(Makefile)

 

(提示:autoscan可以生成configure.in文件的基本框架,但很基本,可其生成的configure.scan文件的基础补充,然后更名为configure.in)

l         编写Makefile.am文件,用于Automake生成Makefile.in文件,Makefile.am文件的大致框架如下:(其中xxxx为应用程序文件名,比如program.c文件的测试程序文件名我建议为check_program.c)

 

TESTS = check_xxxx

noinst_PROGRAMS=check_xxxx

frame_path=xx/check-0.8.0

xxxx_docs =/

     srcfilelist_1/

     srcfilelist_2/

     ......./

     .....

xxxx_SOURCES=/

 srcfilelist_1/

 srcfilelist_2/

 .......

 

EXTRA_DIST = $(xxxx_docs)

 

INCLUDES = -I$(frame_path)/src -I$(other_path)/include

LDADD= /$(frame_path)/src/libcheck.a

CLEANFILES=*.*~

 

Makefile.am有很许多标记,可以参阅相应文档。但常用的如:noinst_PROGRAMS为生成的可执行文件,xxxx_SOURCES(应用程序名加后辍_SOURCES)为源文件列表,EXTRA_DIST为发布程序时不需要的文件列表(用此方法可以将测试文件去掉)INCLUDES为要包含的头文件路径,check的头文件位置在其安装目录下的src中;LDADD为要链接的库文件名,libcheck.acheck测试框架的库文件;)

l         使用Automake –a –-foreign来生成Makefile.in文件,--foreign是为了生成几个外部文件如install.sh等,如果已有这些文件则可以省略这个参数;

l         使用Autoconf来生成configure执行脚本;然后执行./configure来生成Makefile文件;

l         执行make来生成可执行程序;

 

3.2.2 建立测试用例:

1、以程序文件名加前辍“check_”命名测试单元文件名,比如money.c文件的测试单元文件命名为check_money.c

2、加入测试框架头文件以及要测试的单元头文件,以check_money为例:

头文件:money.h;源文件:money.c;测试单元文件:check_money.c

测试文件框架如下:

#include <stdlib.h>

#include <check.h>

#include "money.h"

/*建立必要的测试变量,Moneymoney.h中定义的结构struct money*/

Money *five_dollars;

/*单元测试初始化函数*/

void setup (void)

{

  five_dollars = money_create(5, "USD");

}

/*单元测试结束函数*/

void teardown (void)

{

  money_free (five_dollars);

}

 

/*单元测试用例,用例名为test_create*/

/*test functions: money_amout()*/

START_TEST(test_create)

{

  /*功能性测试,属黑盒测试*/

  /*normal test*/

  fail_unless (money_amount(five_dollars) = = 5,

           "Amount not set correctly on creation");

  fail_unless (strcmp(money_currency(five_dollars),"USD") = = 0,

           "Currency not set correctly on creation");

  /*条件及错误路径测试,属白盒测试*/

  /*extra test*/

}

END_TEST

 

/*单元测试用例,用例名为test_net_create*/

START_TEST(test_neg_create)

{

  Money *m = money_create(-1, "USD");

  fail_unless (m = = NULL, "NULL should be returned on attempt to create with a negative amount");

}

END_TEST

 

/*单元测试用例,用例名为test_net_create*/

START_TEST(test_zero_create)

{

  Money *m = money_create(0, "USD");

  fail_unless (money_amount(m) = = 0,

           "Zero is a valid amount of money");

}

END_TEST

 

/*单元测试组装,将所有单元测试组装到一个“箱子”里面,“箱子”名为Money*/

Suite *money_suite (void)

{

  Suite *s = suite_create("Money");

 

  /*测试用例分组*/

  TCase *tc_core = tcase_create("Core");

  TCase *tc_limits = tcase_create("Limits");

 

  /*将分组加入“箱子”

suite_add_tcase (s, tc_core);

  suite_add_tcase (s, tc_limits);

 

/*分别将不同用例加入分组*/

  tcase_add_test (tc_core, test_create);

  tcase_add_checked_fixture (tc_core, setup, teardown); /*此用例注册初始化和结束函数*/

       /*以下用例将不注册初始化和结束函数*/

  tcase_add_test (tc_limits, test_neg_create);

  tcase_add_test (tc_limits, test_zero_create);

  return s;

}

 

/*执行测试用例*/

int main (void)

{

  int nf;

  Suite *s = money_suite();

  SRunner *sr = srunner_create(s);

  srunner_run_all (sr, CK_NORMAL);

  nf = srunner_ntests_failed(sr);

  srunner_free(sr);

  suite_free(s);

  return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;

}

 

3.2.3 制作发行版:

制作发行版只须配置另外一份Makefile.am,在此文件中的源文件列表加入执行主体,即应用程序包含main函数的文件;也可在制作测试版的Makefile.am中加入发行版的配置,这样就可以直接生成测试版程序和发行版程序。

 

单元测试作业指导书(三)

3.3.2 使用Junit测试EJB3.3.2.1安装JUnit和JunitEE你需要将junit.jar和junitee.jar加入到J2EE应用程序的CLASSPATH中。       一般地,将...
  • samlet
  • samlet
  • 2003年11月09日 23:06
  • 766

单元测试作业指导书(四)

这一部分是Junit工具的简单使用说明,作为作业指导书的附件。 本文简单地介绍了如何使用Junit编写和组织自己的单元测试代码。 l         简单的测试用例如何写测试代码呢?最简单的方式当然是...
  • samlet
  • samlet
  • 2003年11月09日 23:06
  • 894

单元测试作业指导书(二)

这是我以前任项目经理时,编写的关于单元测试方面的作业指导书,针对多种开发环境叙述怎么进行单元测试以及环境配置,现在整理了一下。应该对大家有所帮助。这是第二部分。 3.3  JAVA标准3.3.1测试环...
  • samlet
  • samlet
  • 2003年11月09日 23:05
  • 694

C/C++单元测试理论精要(一)

内容介绍     本系列文章根据《单元测试与VU2.6应用》视频讲座的理论部分整理而成,主要讨论四个问题:为什么需要单元测试?怎样征服可测性难题?怎样才能高效率测试?怎样保证测试效果?重点阐述单元测试...
  • dellfox
  • dellfox
  • 2010年04月14日 11:52
  • 10243

单元测试就是白盒测试吗?

 有一点,需要关注,单元测试是测试阶段.单元测试阶段.而白盒测试是测试方法.测试阶段的有:UT/IT/ST/BBIT/SDV/SIT/SVT/BETA.测试方法可分为三大类:白盒/灰盒/黑盒/当然,在...
  • lyg21th
  • lyg21th
  • 2007年09月09日 23:12
  • 1043

聊聊单元测试(一)——EasyMock

一、单元测试是保证软件质量的重要方法。 单元测试是对系统中某个模块功能的验证,但我们总会遇到这样那样的问题,导致测试代码很难编写。最直接的一个原因便是强耦合关系,被测试者依赖一些不容易构造,...
  • shan9liang
  • shan9liang
  • 2014年07月11日 10:00
  • 4062

CEMS维护方法及注意事项

CEMS维护方法及注意事项1※预处理流程请参考设备的技术资料。2、             气密性检查的方法采用排除法进行检查。A、首先将针形阀关闭。B、取下分水器样气管路,将口堵住,观察气体分析仪的...
  • yanghaiping1984
  • yanghaiping1984
  • 2011年01月20日 20:20
  • 1108

关于单元测试中配置文件不能找到的问题解决办法

在项目的开发过程中,业务层和数据库层需要进行单元测试,在单元测试的代码编写好后,运行时,总是出现异常,对代码进行跟踪后,发现是在数据库层读取配置文件时不能正确读取的原因,由于项目的数据库层使用的是别的...
  • SeaverDing
  • SeaverDing
  • 2008年03月13日 17:48
  • 2583

用EasyMock进行单元测试:什么是EasyMoc

原文:http://www.zhlwish.com/2012/06/29/easymock-1/ 用EasyMock进行单元测试:什么是EasyMock 发: 周亮 我们都知道单元测试,也...
  • xiongmc
  • xiongmc
  • 2013年07月02日 19:31
  • 1286

如何进行单元测试

摘要:单元测试是软件测试的基础,本文详细的论述了单元测试的两个步骤人工静态检查法与动态执行跟踪法,所需执行的工作项目及相关的策略和方法。通过对这两个步骤的描述作者将多年的单元测试经验及测试理论注入于全...
  • zhongguoren666
  • zhongguoren666
  • 2013年09月17日 09:19
  • 5319
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:单元测试作业指导书(一)
举报原因:
原因补充:

(最多只允许输入30个字)