TDD与VTDD系列(二):CppUnit的改进与使用(2)
来源:互联网 发布:男士美图软件 编辑:程序博客网 时间:2024/06/05 13:28
4 测试过程
示例类定义如下:
class CMyClass
{
public:
//加法函数
int Add(int a, int b);
//计算空调制冷器运行时间
int WorkTime(int* pSecond);
};
加法函数Add()是入门示例,WorkTime()是接近应用的示例,功能是计算空调制冷器运行时间,需调用桩代码取得环境温度。测试过程,使用VC6.0。
假设CppUnit安装目录为D:/CppUnit/CppUnit,被测试文件MyClass.cpp和MyClass.h位于D:/CppUnit/Project目录。
1、用VC6.0建立一个一程,即测试工程。第一步左边选择MFC AppWizard(exe),工程名为TestProject,存放位置与Project并列,即存放于D:/CppUnit/TestProject。第二步选择Dialog based,点击Finish。这个示例使用了图形界面,所以要建立一个对话框工程。
2、把文件CppUnitPub.h和TestRun.cpp拷贝到D:/CppUnit/TestProject。
3、拷贝TestClassName.cpp和TestClassName.h文件到D:/CppUnit/TestProject,并重命名文件,将文件名中ClassName替换为实际类名。这里,被测试类名是CMyClass,因此,把文件名改为TestMyClass.cpp/.h。
用文本编辑工具如EditPlus打开这两个文件,进行以下替换:
TestClassName替换为TestMyClass。
ClassName替换为CMyClass。
TestHeaderName替换为TestMyClass.h。
HeaderName替换为MyClass.h。
4、将2、3拷贝和修过的文件、以及被测试类的文件(即D:/CppUnit/Project目录下的MyClass.cpp/.h)加入测试工程,方法是在VC6.0的Project菜单,单击Add files…。
5、设置头文件搜索目录,包括CppUnit,以及产品项目的头文件目录:VC6.0->Project->Setting->C++,Category选择Preprocessor,在Additional include directories中添加搜索目录:D:/CPPUNIT/CPPUNIT/include,D:/CPPUNIT/Project。
6、加入CppUnit的静态和动态库。VC6.0->Project->Setting->Link,Category选择Input,Application library path填写D:/CPPUNIT/CPPUNIT/lib。将CppUnit目录下的TestRunner.dll文件拷贝到D:/CppUnit/TestProject。
7、被测试函数WorkTime()调用了一个未实现的函数,要用桩来代替,后面再介绍桩代码编写,先把其中的代码行success = GetTemperature(&temperature);前加上注释符//。如果设定过程没有错误,这时应该可以通过编译。
8、在CTestProjectApp::InitInstance()函中的开头添加以下代码:
void TestRunAll();
TestRunAll();
return FALSE;
9、在TestRun.cpp文件的TestRunAll()函数中加入测试类:runner.addTest(TestMyClass::GetSuite());
10、编写CMyClass::Add()函数的测试函数,在TestMyClass.cpp文件中添加如下代码:
void TestCMyClass::testAdd()
{
CASE_BEGIN("");
int a = 1;
int b = 1;
int ret = pObj->Add(a, b);
CPPUNIT_ASSERT_EQUAL(2, ret);
CASE_END();
CASE_BEGIN("");
int a = 10;
int b = 10;
int ret = pObj->Add(a, b);
CPPUNIT_ASSERT_EQUAL(20, ret);
CASE_END();
}
在TestMyClass.h文件中添加测试函数声明void testAdd();并在CPPUNIT_TEST_SUITE宏内添加注册代码CPPUNIT_TEST(testAdd);
编译并运行后会显示CppUnit的图形界面,点击“Browse”,选择要执行的测试,再点击“Run”,即会显示测试结果。由于CMyClass::Add()函数中把+写成了-,所以测试会失败,修改后测试通过。
11、编写CMyClass::WorkTime()函数的测试函数,先把7所添加的注释符删除。这个函数首先调用int GetTemperature(int* pTemperature)函数取得环境温度,然后根据环境温度和预设的目标温度的差,计算制冷器的运行时间。在TestMyClass.cpp添加测试函数:
extern int gExpectTemperature;
void TestMyClass::testWorkTime()
{
CASE_BEGIN("failed");
gExpectTemperature = 25;
int second = 0;
int ret = pObj->WorkTime(&second);
CPPUNIT_ASSERT_EQUAL(0, ret);
CPPUNIT_ASSERT_EQUAL(0, second);
CASE_END();
CASE_BEGIN("ok-23");
gExpectTemperature = 25;
int second = 0;
int ret = pObj->WorkTime(&second);
CPPUNIT_ASSERT_EQUAL(0, ret);
CPPUNIT_ASSERT_EQUAL(0, second);
CASE_END();
CASE_BEGIN("ok-28");
gExpectTemperature = 25;
int second = 0;
int ret = pObj->WorkTime(&second);
CPPUNIT_ASSERT_EQUAL(1, ret);
CPPUNIT_ASSERT_EQUAL(180, second);
CASE_END();
CASE_BEGIN("ok-25");
gExpectTemperature = 25;
int second = 0;
int ret = pObj->WorkTime(&second);
CPPUNIT_ASSERT_EQUAL(0, ret);
CPPUNIT_ASSERT_EQUAL(0, second);
CASE_END();
}
在TestMyClass.h文件中添加测试函数声明void testWorkTime ();并在CPPUNIT_TEST_SUITE宏内添加注册代码CPPUNIT_TEST(testWorkTime);
现在编译还无法通过,因为GetTemperature()未实现。假设我们对GetTemperature()函数的测试需求如下表,要使用例与桩输出匹配,如何编写桩代码呢?可以用命名法来匹配用例与桩输出。
用例
返回值
出参(环境温度)
1
0(取环境温度失败)
2
1(取环境温度成功)
23
3
1
25
4
1
28
在测试代码中,每个用例的第一行可以给用例命名,如CASE_BEGIN("failed"),表示取环境温度失败,CASE_BEGIN("ok-23"),表示取环境温度成功,值为23。
在测试工程目录下新建文件Stub.cpp,并加入测试工程,编写桩代码,如下:
#include "stdafx.h"
#include "CppUnitPub.h"
int GetTemperature(int* pTemperature)
{
if(caseNameIs("failed"))
return 0;
if(caseNameIs("ok-23"))
{
*pTemperature = 23;
return 1;
}
if(caseNameIs("ok-25"))
{
*pTemperature = 25;
return 1;
}
if(caseNameIs("ok-28"))
{
*pTemperature = 28;
return 1;
}
return 0;
}
桩代码调用caseNameIs()来判断当前用例名,并输出合适的值。
本例中,如果GetTemperature()调用的是实际代码,在测试时称为不可控,即无法控制真实的环境温度使其满足测试的需要;如果调用的是桩代码,且桩代码只是空函数,则称为失真,简单的失真可以用命名法解决,但不能解决复杂的失真,例如,GetTemperature()在同一用例中被多次调用,每次要求输出不同;或者桩与被测函数的关系是多对多,这就难于维护桩输出与用例的关系了。另外,编写桩代码也不能解决不可控,假如GetTemperature()也是CMyClass类的成员函数,在不修改产品代码的前提下,无法调用桩。这些问题,就不是开源框架所能解决的了。
- TDD与VTDD系列(二):CppUnit的改进与使用(2)
- TDD与VTDD系列(一):CppUnit的改进与使用(1)
- TDD与VTDD系列(三):TDD概述
- TDD与VTDD系列(五):提升产能1/3的开发方法:VTDD(概述)
- TDD与VTDD系列(四):简单实例演示TDD过程
- CppUnit的缺陷与改进
- CppUnit的缺陷与改进
- CppUnit的缺陷与改进
- CppUnit的缺陷与改进
- TDD再思考----优势、不足与改进
- Linux 下 CppUnit的安装与使用
- CppUnit的安装配置与使用
- CPPunit 1.13.2 + vs2013 配置与使用
- CppUnit入门实践-Tony与Alex的对话系列
- CppUnit入门实践-Tony与Alex的对话系列
- LP 系列第 2 部分:协议的扩展与改进
- TDD的理解与疑问
- 关于iOS TDD&BDD的学习与使用
- SQL server2005中文件备份与恢复
- VB显示透明FLASH效果
- 解决让你崩溃的 GCJ,GCJ for windows 搭建详解
- 网站规划预算
- Makefile中变量的使用
- TDD与VTDD系列(二):CppUnit的改进与使用(2)
- html页面表格导出到excel总结
- CrossTools交叉编绎工具!
- http消息头
- trjtyrtj
- BLOG开通
- 为什么要深入数学的世界
- 养成良好的代码风格---c#变量命名规则
- The Joel Test