使用CPPUNIT对MFC程序进行测试

载自:http://blog.csdn.net/shuilan0066/article/details/7696640

1  资源下载

 

  使用的是cppunit-1.12.1 ,在网上下载后 需要自己编译 ,编译过程中可能出现各种问题

  在此,将自己编译好的软件放在了资源中,可以直接使用: http://download.csdn.net/detail/shuilan0066/4395617,免去了重复编译的工作。

 

   资源中同时包含CPPUnitProjectWizard

 

2  环境配置

   cppunit不能直接使用,必须先配置好运行环境。

 

   CPPUNIT环境配置:

   比如,CPPUNIT安装在E盘               E:\cppunit-1.12.1

 

   1)        定义环境变量  CPPUNITDIR

                 变量值为: E:\cppunit-1.12.1

        

   2)        修改环境变量PATH,在PATH原有路径的最后,添加    %CPPUNITDIR%/lib,    以便程序加载时能找到 cppunit_dll.dll

 

   3)        在开发环境中,设置好Include/Lib路径

 

                项目-->属性-- 》C/C++ 》常规 下 的     附加包含目录中添加Include :     $(CPPUNITDIR)\Include

 

                项目-->属性-- 》连接器 》常规 下 的     附加库目录中添加lib:                   $(CPPUNITDIR)\lib



  CPPUnitProjectWizard环境配置:

     1)      解压缩后,复制如下两个文件到Visual Studio 8安装目录下的 VCProjects 文件夹中  … /VC/vcprojects

                     CPPUnitProjectWizard.vsdir - 为向导命名

        CPPUnitProjectWizard.vsz - VS知道从哪里找到向导

 

    2)     把整个CPPUnitProjectWizard解决方案文件夹复制到您的Visual Studio 8安装目录下的VCWizards文件夹中,比如,我放在…/VC/VCWizards

                           然后用记事本编辑CPPUnitProjectWizard.vsz,定义参数 ABSOLUTE_PATH

        Param="ABSOLUTE_PATH = …VC/VCWizards/ CPPUnitProjectWizard"

3 CPPUNIT 宏说明

   CPPUNIT 通过以下宏来判断是否正确

     

  1. CPPUNIT_ASSERT是一个宏,判断后面的参数是否正确,CPPUNIT还有很多宏,如  
  2.   CPPUNIT_ASSERT(condition)                      // 确信condition为真   
  3.   CPPUNIT_ASSERT_MESSAGE(message, condition)     // 当condition为假时失败, 并打印message   
  4.   
  5. CPPUNIT_FAIL(message)                          // 当前测试失败, 并打印message   
  6.   
  7. CPPUNIT_ASSERT_EQUAL(expected, actual)         // 确信两者相等   
  8.   CPPUNIT_ASSERT_EQUAL_MESSAGE(message, expected, actual) // 失败的同时打印message   
  9.   
  10. CPPUNIT_ASSERT_DOUBLES_EQUAL(expected, actual, delta)   // 当expected和actual之间差大于delta时失败  
            CPPUNIT_ASSERT是一个宏,判断后面的参数是否正确,CPPUNIT还有很多宏,如
              CPPUNIT_ASSERT(condition)                      // 确信condition为真
              CPPUNIT_ASSERT_MESSAGE(message, condition)     // 当condition为假时失败, 并打印message

            CPPUNIT_FAIL(message)                          // 当前测试失败, 并打印message

            CPPUNIT_ASSERT_EQUAL(expected, actual)         // 确信两者相等
              CPPUNIT_ASSERT_EQUAL_MESSAGE(message, expected, actual) // 失败的同时打印message

            CPPUNIT_ASSERT_DOUBLES_EQUAL(expected, actual, delta)   // 当expected和actual之间差大于delta时失败

 

4  简单示例

 

     1)        打开vs2005,新建一个MFC 对话框项目名为 CppUnit

  2)    设置项目属性

 

                项目-->属性-- 》C/C++ 》常规 下 的     附加包含目录中添加Include :     $(CPPUNITDIR)\Include

 

                项目-->属性-- 》连接器 》常规 下 的     附加库目录中添加lib:           $(CPPUNITDIR)\lib

 

    3) 打开CppUnit.cpp文件,增加包含文件和声明使用库代码

 

  1. #include <cppunit/ui/mfc/TestRunner.h>   
  2.   
  3. #include <cppunit/extensions/TestFactoryRegistry.h>   
  4.   
  5. #pragma comment(lib, "cppunitd.lib")   
  6.   
  7. #pragma comment(lib, "testrunnerud.lib")  
#include <cppunit/ui/mfc/TestRunner.h>

#include <cppunit/extensions/TestFactoryRegistry.h>

#pragma comment(lib, "cppunitd.lib")

#pragma comment(lib, "testrunnerud.lib")


 

注:如果为Release版本声明使用库文件为

 

  1. #pragma comment(lib, "cppunit.lib")   
  2.   
  3. #pragma comment(lib, "testrunner.lib")  
#pragma comment(lib, "cppunit.lib")

#pragma comment(lib, "testrunner.lib")


  4)修改InitInstance()函数

      注释掉了对话框

      增加了CPPUNIT_NS 测试

  1. BOOL CCppUnitApp::InitInstance()  
  2. {  
  3.     // 如果一个运行在 Windows XP 上的应用程序清单指定要   
  4.     // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,   
  5.     //则需要 InitCommonControlsEx()。否则,将无法创建窗口。   
  6.     INITCOMMONCONTROLSEX InitCtrls;  
  7.     InitCtrls.dwSize = sizeof(InitCtrls);  
  8.     // 将它设置为包括所有要在应用程序中使用的   
  9.     // 公共控件类。   
  10.     InitCtrls.dwICC = ICC_WIN95_CLASSES;  
  11.     InitCommonControlsEx(&InitCtrls);  
  12.   
  13.     CWinApp::InitInstance();  
  14.   
  15.     AfxEnableControlContainer();  
  16.   
  17.     // 标准初始化   
  18.     // 如果未使用这些功能并希望减小   
  19.     // 最终可执行文件的大小,则应移除下列   
  20.     // 不需要的特定初始化例程   
  21.     // 更改用于存储设置的注册表项   
  22.     // TODO: 应适当修改该字符串,   
  23.     // 例如修改为公司或组织名   
  24.     SetRegistryKey(_T("应用程序向导生成的本地应用程序"));  
  25.   
  26. //  注释掉了这一段   
  27. //  CCppUnitDlg dlg;   
  28. //  m_pMainWnd = &dlg;   
  29. //  INT_PTR nResponse = dlg.DoModal();   
  30. //  if (nResponse == IDOK)   
  31. //  {   
  32. //      // TODO: 在此处放置处理何时用“确定”来关闭   
  33. //      //  对话框的代码   
  34. //  }   
  35. //  else if (nResponse == IDCANCEL)   
  36. //  {   
  37. //      // TODO: 在此放置处理何时用“取消”来关闭   
  38. //      //  对话框的代码   
  39. //  }   
  40.   
  41.     // 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,   
  42.     //  而不是启动应用程序的消息泵。   
  43.   
  44. //增加如下代码   
  45.   
  46.   
  47.     CPPUNIT_NS::MfcUi::TestRunner runner;  
  48.     runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );  
  49.     runner.run();  
  50.   
  51.     return FALSE;  
  52. }  
BOOL CCppUnitApp::InitInstance()
{
	// 如果一个运行在 Windows XP 上的应用程序清单指定要
	// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
	//则需要 InitCommonControlsEx()。否则,将无法创建窗口。
	INITCOMMONCONTROLSEX InitCtrls;
	InitCtrls.dwSize = sizeof(InitCtrls);
	// 将它设置为包括所有要在应用程序中使用的
	// 公共控件类。
	InitCtrls.dwICC = ICC_WIN95_CLASSES;
	InitCommonControlsEx(&InitCtrls);

	CWinApp::InitInstance();

	AfxEnableControlContainer();

	// 标准初始化
	// 如果未使用这些功能并希望减小
	// 最终可执行文件的大小,则应移除下列
	// 不需要的特定初始化例程
	// 更改用于存储设置的注册表项
	// TODO: 应适当修改该字符串,
	// 例如修改为公司或组织名
	SetRegistryKey(_T("应用程序向导生成的本地应用程序"));

//  注释掉了这一段
// 	CCppUnitDlg dlg;
// 	m_pMainWnd = &dlg;
// 	INT_PTR nResponse = dlg.DoModal();
// 	if (nResponse == IDOK)
// 	{
// 		// TODO: 在此处放置处理何时用“确定”来关闭
// 		//  对话框的代码
// 	}
// 	else if (nResponse == IDCANCEL)
// 	{
// 		// TODO: 在此放置处理何时用“取消”来关闭
// 		//  对话框的代码
// 	}

	// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
	//  而不是启动应用程序的消息泵。

//增加如下代码


	CPPUNIT_NS::MfcUi::TestRunner runner;
	runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );
	runner.run();

	return FALSE;
}


      

编译运行出现如下图界面,此时未加任何用例的单元测试例子界面就出来了:

 

 

 

   5)添加测试代码

         a)     添加一个c++类example,其基类是public CPPUNIT_NS::TestFixture

        b)     修改example.h

 

  1. #pragma once   
  2.   
  3. #include <cppunit/extensions/HelperMacros.h>   
  4.   
  5. #include <cppunit/TestFixture.h>   
  6.   
  7.   
  8.   
  9. class example :public CPPUNIT_NS::TestFixture  
  10.   
  11. {  
  12.   
  13.     CPPUNIT_TEST_SUITE(example);  
  14.   
  15.     CPPUNIT_TEST_SUITE_END();  
  16.   
  17. public:  
  18.   
  19.     example(void);  
  20.   
  21.     ~example(void);  
  22.   
  23.   
  24.   
  25. };  
#pragma once

#include <cppunit/extensions/HelperMacros.h>

#include <cppunit/TestFixture.h>



class example :public CPPUNIT_NS::TestFixture

{

	CPPUNIT_TEST_SUITE(example);

	CPPUNIT_TEST_SUITE_END();

public:

	example(void);

	~example(void);



};

 

      c) 修改example.c

 

  1. #include "StdAfx.h"   
  2. #include "example.h"   
  3.   
  4. CPPUNIT_TEST_SUITE_REGISTRATION(example);  
  5.   
  6. example::example(void)  
  7. {  
  8. }  
  9.   
  10. example::~example(void)  
  11. {  
  12. }  
#include "StdAfx.h"
#include "example.h"

CPPUNIT_TEST_SUITE_REGISTRATION(example);

example::example(void)
{
}

example::~example(void)
{
}

 

     d)  此时编译,可发现出现了测试包:

 


  e)      添加测试包初始化、结束函数setUp,tearDown(注意大小写)。以及添加测试用例testcase1,testcase2

            example.h

  1. #pragma once   
  2.   
  3. #include <cppunit/extensions/HelperMacros.h>   
  4.   
  5. #include <cppunit/TestFixture.h>   
  6.   
  7.   
  8.   
  9. class example :public CPPUNIT_NS::TestFixture  
  10.   
  11. {  
  12.   
  13.     CPPUNIT_TEST_SUITE(example);  
  14.   
  15.     CPPUNIT_TEST(testcase1);  
  16.     CPPUNIT_TEST(testcase2);  
  17.   
  18.     CPPUNIT_TEST_SUITE_END();  
  19.   
  20. public:  
  21.   
  22.     example(void);  
  23.   
  24.     ~example(void);  
  25.   
  26. public:  
  27.     void setUp();  
  28.     void tearDown();  
  29.     void testcase1();  
  30.     void testcase2();  
  31.   
  32.   
  33. };  
#pragma once

#include <cppunit/extensions/HelperMacros.h>

#include <cppunit/TestFixture.h>



class example :public CPPUNIT_NS::TestFixture

{

	CPPUNIT_TEST_SUITE(example);

	CPPUNIT_TEST(testcase1);
	CPPUNIT_TEST(testcase2);

	CPPUNIT_TEST_SUITE_END();

public:

	example(void);

	~example(void);

public:
	void setUp();
	void tearDown();
	void testcase1();
	void testcase2();


};


         example.cpp

  1. #include "StdAfx.h"   
  2. #include "example.h"   
  3.   
  4. CPPUNIT_TEST_SUITE_REGISTRATION(example);  
  5.   
  6. example::example(void)  
  7. {  
  8. }  
  9.   
  10. example::~example(void)  
  11. {  
  12. }  
  13.   
  14. void example::testcase1()  
  15. {  
  16.     AfxMessageBox((LPCTSTR)_T("I am testcase1"),MB_OK,0);  
  17.   
  18. }  
  19.   
  20. void example::testcase2()  
  21. {  
  22.     AfxMessageBox((LPCTSTR)_T("I am testcase2"),MB_OK,0);  
  23. }  
  24.   
  25.   
  26.   
  27.   
  28.   
  29. void example::setUp()  
  30. {  
  31.     AfxMessageBox((LPCTSTR)_T("I am setup"),MB_OK,0);  
  32. }  
  33.   
  34. void example::tearDown()  
  35. {  
  36.     AfxMessageBox((LPCTSTR)_T("I am teardown"),MB_OK,0);  
  37. }  
#include "StdAfx.h"
#include "example.h"

CPPUNIT_TEST_SUITE_REGISTRATION(example);

example::example(void)
{
}

example::~example(void)
{
}

void example::testcase1()
{
	AfxMessageBox((LPCTSTR)_T("I am testcase1"),MB_OK,0);

}

void example::testcase2()
{
	AfxMessageBox((LPCTSTR)_T("I am testcase2"),MB_OK,0);
}





void example::setUp()
{
	AfxMessageBox((LPCTSTR)_T("I am setup"),MB_OK,0);
}

void example::tearDown()
{
	AfxMessageBox((LPCTSTR)_T("I am teardown"),MB_OK,0);
}


   说明,每一个用例,都会调用setUp和tearDown 这是CPPUNIT内部默认的

 

f)        添加其他用例

  1. #pragma once   
  2.   
  3. #include <cppunit/extensions/HelperMacros.h>   
  4.   
  5. #include <cppunit/TestFixture.h>   
  6.   
  7.   
  8.   
  9. class example :public CPPUNIT_NS::TestFixture  
  10.   
  11. {  
  12.   
  13.     CPPUNIT_TEST_SUITE(example);  
  14.   
  15.     CPPUNIT_TEST(testcase1);  
  16.     CPPUNIT_TEST(testcase2);  
  17.     CPPUNIT_TEST(testcase3);  
  18.     CPPUNIT_TEST(testcase4);  
  19.   
  20.     CPPUNIT_TEST_SUITE_END();  
  21.   
  22. public:  
  23.   
  24.     example(void);  
  25.   
  26.     ~example(void);  
  27.   
  28. public:  
  29.     void setUp();  
  30.     void tearDown();  
  31.     void testcase1();  
  32.     void testcase2();  
  33.     void testcase3();  
  34.     void testcase4();  
  35.   
  36.   
  37. };  
#pragma once

#include <cppunit/extensions/HelperMacros.h>

#include <cppunit/TestFixture.h>



class example :public CPPUNIT_NS::TestFixture

{

	CPPUNIT_TEST_SUITE(example);

	CPPUNIT_TEST(testcase1);
	CPPUNIT_TEST(testcase2);
	CPPUNIT_TEST(testcase3);
	CPPUNIT_TEST(testcase4);

	CPPUNIT_TEST_SUITE_END();

public:

	example(void);

	~example(void);

public:
	void setUp();
	void tearDown();
	void testcase1();
	void testcase2();
	void testcase3();
	void testcase4();


};


 

  1. #include "StdAfx.h"   
  2. #include "example.h"   
  3.   
  4. CPPUNIT_TEST_SUITE_REGISTRATION(example);  
  5.   
  6. example::example(void)  
  7. {  
  8. }  
  9.   
  10. example::~example(void)  
  11. {  
  12. }  
  13.   
  14. void example::testcase1()  
  15. {  
  16.     AfxMessageBox((LPCTSTR)_T("I am testcase1"),MB_OK,0);  
  17.   
  18. }  
  19.   
  20. void example::testcase2()  
  21. {  
  22.     AfxMessageBox((LPCTSTR)_T("I am testcase2"),MB_OK,0);  
  23. }  
  24.   
  25.   
  26. void example::testcase3()  
  27. {  
  28.     CPPUNIT_ASSERT(1==1);  
  29. }  
  30.   
  31. void example::testcase4()  
  32. {  
  33.     CPPUNIT_ASSERT(1==2);  
  34. }  
  35.   
  36.   
  37.   
  38.   
  39. void example::setUp()  
  40. {  
  41.     AfxMessageBox((LPCTSTR)_T("I am setup"),MB_OK,0);  
  42. }  
  43.   
  44. void example::tearDown()  
  45. {  
  46.     AfxMessageBox((LPCTSTR)_T("I am teardown"),MB_OK,0);  
  47. }  
#include "StdAfx.h"
#include "example.h"

CPPUNIT_TEST_SUITE_REGISTRATION(example);

example::example(void)
{
}

example::~example(void)
{
}

void example::testcase1()
{
	AfxMessageBox((LPCTSTR)_T("I am testcase1"),MB_OK,0);

}

void example::testcase2()
{
	AfxMessageBox((LPCTSTR)_T("I am testcase2"),MB_OK,0);
}


void example::testcase3()
{
	CPPUNIT_ASSERT(1==1);
}

void example::testcase4()
{
	CPPUNIT_ASSERT(1==2);
}




void example::setUp()
{
	AfxMessageBox((LPCTSTR)_T("I am setup"),MB_OK,0);
}

void example::tearDown()
{
	AfxMessageBox((LPCTSTR)_T("I am teardown"),MB_OK,0);
}


 

g)             单元测试结果

假如测试中所有断言都通过,则结果为绿色。

假如由一个断言失败,则显示红色,下面显示出错位置,且双击可以找到源代码位置。

 

 

5  测试另一个项目中的代码

 

   新建一对话框项目DlgTest,检测对话框项目的函数CDlgTestDlg::Add。

 

   1) 将CPPUNIT 测试项目 和被测试项目 放在同一目录下, 并在同一个解决方案中打开

   2) 设置测试环境,将被测项目的路径添加到附加包含路径中

            比如,被测项目DlgTest的路径为: E:\TEST\DlgTest\DlgTest   

            则在CPPUNIT项目属性--》C/C++-》常规    附加包含路径中添加 E:\TEST\DlgTest\DlgTest

            因为之前添加了CPPUNIT的Include路径 

            所以,添加被测路径之后的值为:          "$(CPPUNITDIR)\Include";E:\TEST\DlgTest\DlgTest

    3) 使用  添加--》现有项功能 将被测的DlgTestDlg.h 和DlgTestDlg.cpp添加到CPPUnit中

 

   4) 修改CPPUNIT单元测试项目中的测试单元example

 

             修改example.h  

             添加被测函数的头文件 

  1. #include "DlgTestDlg.h"  
#include "DlgTestDlg.h"

          

            修改example.cpp

            在此,测试对话框CDlgTestDlg中的Add函数

  1. void example::testcase1()  
  2. {  
  3. //  AfxMessageBox((LPCTSTR)_T("I am testcase1"),MB_OK,0);   
  4.   
  5.   
  6.     CDlgTestDlg dlg;  
  7.   
  8.     int i=dlg.Add(3,5);  
  9.     CPPUNIT_ASSERT(i==9);  
  10.   
  11. }  
void example::testcase1()
{
//	AfxMessageBox((LPCTSTR)_T("I am testcase1"),MB_OK,0);


	CDlgTestDlg dlg;

	int i=dlg.Add(3,5);
    CPPUNIT_ASSERT(i==9);

}


  5) 编译运行 查看测试结果

           

 

       CPPUNIT测试项目模板 保存在资源 http://download.csdn.net/detail/shuilan0066/4396670 , 可以下载后,将其放置到被测项目的等同目录下,修改参数,进行测试

 


           

参考资料:

http://blog.csdn.net/ainiyidiandian/article/details/5788240  

http://morningspace.51.net/resource/cppunit/cppunit_anno.html    

http://www.cppblog.com/ace/archive/2006/08/04/10842.html

http://blog.csdn.net/wincol/article/details/5789644

http://blog.csdn.net/alicehyxx/article/details/4483681

http://blog.csdn.net/jinjunmax_78/article/details/2033755

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值