主题:Cantata++针对完整应用的测试技术及MFC 程序测试技巧
1 介绍
本技术细节适用于已经接受过Cantata++ 初级培训的人员,重点介绍 Cantata++ 应用级别的测试技术与技巧。
1.1 概述
对于完整应用的覆盖率测试(系统级测试),使用 Cantata++ Stand-alone 方式可以根据所选择的插桩方式建
立执行代码,执行后得到原始的覆盖率数据。通过一个独立的测试脚本分析得到最终的测试报告。
本技术细节介绍绑定方式,编写 C++ 测试脚本控制覆盖率测试和封装函数。
针对MFC 程序,我们不能把某个单独的类或成员函数分割出来进行单元测试。怎样从被测程序中直接获得
测试信息,而不破坏软件的运行?我们只能在MFC 程序应用的测试中联合单元/集成测试控制,访问私有数
据,封装控制并测试验证某些函数。最后自动获得验证报告和文本形式的覆盖率报告,而不是先取得原始覆
盖率数据 (.cov) 然后再生成文本报告 (.ctr) 文件。
2 完整应用的测试技术
针对不同的应用编写测试脚本的形式也略有不同,下边就MFC 程序详细说明测试步骤。
2.1 测试脚本
第一件事情是建立测试脚本,通常情况时 Cantata++ 的测试脚本包含 main 函数,但是对于完整的应用程序,
它已经包含了 main ( 或与之等价的) 函数。我们不想改变被测代码。这种情况下我们可以在被测工程中加入
一个额外的文件作为测试脚本。使用静态的测试类我们来建立测试脚本。构造静态类作为应用的开始,析构
作为结束,我们可以在构造函数中放置 Cantata++ 的开始代码 (START_SCRIPT, START_TEST) ,在析构
函数中放置 Cantata++ 的结束代码 (END_TEST, END_SCRIPT) ,例如:
struct TEST_CLASS(application)
{
TEST_CLASS(application)();
~TEST_CLASS(application)();
};
TEST_CLASS(application) instance;
测试类将在应用的起始和析构时建立和关闭。
2.1.1 构造函数
TEST_CLASS(application)::TEST_CLASS(application)()
{
OPEN_LOG("results.ctr");
START_SCRIPT("applcation",false); // Output to file (not stdout)
START_TEST("unit/system test");
}
2.1.2 析构函数
TEST_CLASS(application)::~TEST_CLASS(application)()
{
END_TEST();
END_SCRIPT(false);
2004 年3 月主办:北京旋极信息技术有限公司第三期总第3 期
}
测试时代 Testing Time
2.1.3 其他细节
测试脚本中应该包含 Cantata++ 的相关头文件:
#include <cppth.h>
#include <cppcr.h>
这是一个基本的测试脚本,上边所有的代码可以加入一个源文件,编译连接到被测工程,自动的产生测试
报告。编辑测试脚本,加入覆盖率测试验证或其他需要测试的内容,从而实现测试目的。例如在析构函数中
加入:
TEST_CLASS(application)::~TEST_CLASS(application)
{
END_TEST();
REPORT_COVERAGE(cppca_entrypoint_cov,"*"); // 验证入口点覆盖
END_SCRIPT(false);
}
2.2 封装函数
封装函数也可以到测试脚本中,控制调用序列,验证被测类或成员函数的数据。
DEFAULT_EXPECTED_CALLS("{testfunc# wapper_use }");
START_TEST("unit/system test");
或
START_TEST("unit/system test");
EXPECTED_CALLS("{testfunc# wapper_use }");
// Code
END_CALLS();
END_TEST();
在wft 封装文件中的BEFORE 函数中可以定义IF_INSTANCE 作为测试用例,设计输入,例如:
IF_INSTANCE("wapper_use")
{
cppsm_this_object->OperationState=1;
cppsm_this_object->number1=3;
cppsm_this_object->number2=4; //被测对象成员的初始化
return true;
}
在AFTER 函数中检查期望输出,例如:
CHECK(cppsm_this_object->m_number,12);
return;
3 结论:
有成百上千种封装的策略可以应用在系统级的测试上。本文只是给出了一个此类测试的入门方法,我们可以
通过封装的方法进行MFC 程序的单元测试,验证MFC 程序覆盖率,生成HTML 报告。
本技术细节适用于已经接受过Cantata++ 初级培训的人员,重点介绍 Cantata++ 应用级别的测试技术与技巧。
1.1 概述
对于完整应用的覆盖率测试(系统级测试),使用 Cantata++ Stand-alone 方式可以根据所选择的插桩方式建
立执行代码,执行后得到原始的覆盖率数据。通过一个独立的测试脚本分析得到最终的测试报告。
本技术细节介绍绑定方式,编写 C++ 测试脚本控制覆盖率测试和封装函数。
针对MFC 程序,我们不能把某个单独的类或成员函数分割出来进行单元测试。怎样从被测程序中直接获得
测试信息,而不破坏软件的运行?我们只能在MFC 程序应用的测试中联合单元/集成测试控制,访问私有数
据,封装控制并测试验证某些函数。最后自动获得验证报告和文本形式的覆盖率报告,而不是先取得原始覆
盖率数据 (.cov) 然后再生成文本报告 (.ctr) 文件。
2 完整应用的测试技术
针对不同的应用编写测试脚本的形式也略有不同,下边就MFC 程序详细说明测试步骤。
2.1 测试脚本
第一件事情是建立测试脚本,通常情况时 Cantata++ 的测试脚本包含 main 函数,但是对于完整的应用程序,
它已经包含了 main ( 或与之等价的) 函数。我们不想改变被测代码。这种情况下我们可以在被测工程中加入
一个额外的文件作为测试脚本。使用静态的测试类我们来建立测试脚本。构造静态类作为应用的开始,析构
作为结束,我们可以在构造函数中放置 Cantata++ 的开始代码 (START_SCRIPT, START_TEST) ,在析构
函数中放置 Cantata++ 的结束代码 (END_TEST, END_SCRIPT) ,例如:
struct TEST_CLASS(application)
{
TEST_CLASS(application)();
~TEST_CLASS(application)();
};
TEST_CLASS(application) instance;
测试类将在应用的起始和析构时建立和关闭。
2.1.1 构造函数
TEST_CLASS(application)::TEST_CLASS(application)()
{
OPEN_LOG("results.ctr");
START_SCRIPT("applcation",false); // Output to file (not stdout)
START_TEST("unit/system test");
}
2.1.2 析构函数
TEST_CLASS(application)::~TEST_CLASS(application)()
{
END_TEST();
END_SCRIPT(false);
2004 年3 月主办:北京旋极信息技术有限公司第三期总第3 期
}
测试时代 Testing Time
2.1.3 其他细节
测试脚本中应该包含 Cantata++ 的相关头文件:
#include <cppth.h>
#include <cppcr.h>
这是一个基本的测试脚本,上边所有的代码可以加入一个源文件,编译连接到被测工程,自动的产生测试
报告。编辑测试脚本,加入覆盖率测试验证或其他需要测试的内容,从而实现测试目的。例如在析构函数中
加入:
TEST_CLASS(application)::~TEST_CLASS(application)
{
END_TEST();
REPORT_COVERAGE(cppca_entrypoint_cov,"*"); // 验证入口点覆盖
END_SCRIPT(false);
}
2.2 封装函数
封装函数也可以到测试脚本中,控制调用序列,验证被测类或成员函数的数据。
DEFAULT_EXPECTED_CALLS("{testfunc# wapper_use }");
START_TEST("unit/system test");
或
START_TEST("unit/system test");
EXPECTED_CALLS("{testfunc# wapper_use }");
// Code
END_CALLS();
END_TEST();
在wft 封装文件中的BEFORE 函数中可以定义IF_INSTANCE 作为测试用例,设计输入,例如:
IF_INSTANCE("wapper_use")
{
cppsm_this_object->OperationState=1;
cppsm_this_object->number1=3;
cppsm_this_object->number2=4; //被测对象成员的初始化
return true;
}
在AFTER 函数中检查期望输出,例如:
CHECK(cppsm_this_object->m_number,12);
return;
3 结论:
有成百上千种封装的策略可以应用在系统级的测试上。本文只是给出了一个此类测试的入门方法,我们可以
通过封装的方法进行MFC 程序的单元测试,验证MFC 程序覆盖率,生成HTML 报告。