您的位置:首页 > 其它

自动化单元测试的意义

2008-02-19 08:37 260 查看
自动化单元测试的意义

出处

作者:许式伟
写于:2005年3月
背景:WPS Office 2005 (开发代号: V6)
原文:why-unit-test.pdf (pdf格式)

目录

自动化单元测试的重要特征

单元测试的项目意义

单元测试对设计的意义

cppunit for v6

将测试案例写在dll中

常规测试的缺陷

一般是基于手工的,不具备可回归性。因此测试的效率不高。

由于缺乏效率,往往导致测试仅仅针对典型数据,覆盖面往往也很低。

自动化单元测试的重要特征

自动化、可回归性

Quiet

案例的执行安全受控

自动化、可回归性

测试的结果是程序直接检测的,而不是“通过人眼对屏幕上的输出结果的观测”

测试的输入数据和预测结果直接在案例中,除非结果非预期,否则不需要任何输出

因此,并不推荐屏幕输出,或者写可视化的测试单元。

案例的执行不需要人工干预,可随时回放。

因此,我们可以通过大量典型测试数据进行回归,以确保系统的可靠性。

对比:常规测试典型过程

在屏幕上提示输入数据,然后打印结果,通过查看屏幕显示的结果,确认我们的系统是否存在问题。

Quiet

绝对避免在案例执行过程中弹出对话框或者进行其他UI交互。

(调试模式下例外)

案例的执行安全受控

某个测试案例执行的失败(甚至出现了异常),不会导致测试环境的崩溃,也不影响另一个案例的执行结果。

常规测试样例

void main()
{
int n;
for (;;)
{
std::cout << "input n(0 to exit): ";
std::cin >> n;
if (n== 0)
break;
std::cout << "n! = " << fact(n) << std::endl;
}
}


cppunit测试案例

class TestFact : public TestCase
{
public:
CPPUNIT_TEST_SUITE(TestFact);
CPPUNIT_TEST(test);
CPPUNIT_TEST_SUITE_END();

void test()
{
CPPUNIT_ASSERT(fact(3) == 6);
CPPUNIT_ASSERT(fact(4) == 24);
CPPUNIT_ASSERT(fact(5) == 120);
}
};

CPPUNIT_TEST_SUITE_REGISTRATION(TestFact);


单元测试的项目意义

模块更加可控。

及早发现问题,提高模块质量,降低系统测试成本。

加速开发周期。

单元测试与项目控制

单元测试不应该是程序员的个人行为,而与项目进度控制、质量控制息息相关。

通过监测单元测试的情况,来量化模块开发的进度与质量。

要改善项目的控制,必须“做好单元测试”。

不止是要让单元测试成为每个程序员的例行公事,而且要让它变得规范、变得受控。

单元测试的误区

一个很常见误解是:嗯,单元测试,好事啊,只是最近时间很紧,下回做吧。

实际上单元测试大家都会去做,我们提倡单元测试,更大程度上是要达到:

规范单元测试的编写(手段);

最大程度保留下来我们的测试案例;

加速开发周期

一个系统自动化程度越高,则运营成本越低。

单元(模块)是最容易,也是最应该采用自动化测试的。而集成测试、系统测试虽然也有自动化的方法和支持工具,但需要更高额的代价。

单元测试将问题的发现周期缩短,降低bug修复成本。

如果问题在集成测试、系统测试期被发现,那么同样一个问题需要花几倍甚至几十倍的时间进行定位、修复。

单元测试降低了集成测试、系统测试的压力和投入成本。

单元测试的主要检查点

案例的覆盖度

Bug量与Bug反复情况

案例文档的规范

单元测试对设计的意义

设计应该以可测试性为第一目标。

及时发现模块构架调整引发的潜在Bug。

模块的可测试性

可测试性 = 低耦合

环境模拟(依赖的模块、数据输入)

模块设计应该首先保证可测试性。

坚持进行单元测试可提高设计能力。

一个模块可以很方便地进行测试,那么就可以说它是一个设计优良的模块。

发现模块构架调整的潜在Bug

通常模块在架构调整期(代码重构)最容易引入Bug。

只有在模块开发中就不断积累经典数据、以案例的形式固化已知Bug,才可能在架构调整等最容易引发问题的情形下获得最佳效果。

cppunit for v6

引入调试模式

通用的调试开关

有选择的运行测试案例

独特的dll测试模式

调试模式

同一套测试代码,两种工作模式。

cppunit提供了安全可控的自动化测试平台。

但是是代码总会有bug。为了让测试案例可调试,v6在开源的cppunit基础上,结合kfc的调试策略,引入调试模式。

通用的调试开关

/ndebug

进入自动化测试模式。默认为调试模式。

/output:<xmlfile>

输出结果到xml文件。注意:/output:后不能有空格。

默认输出到控制台。

/run:<testclass>[.<testmethod>]

执行<testclass>类所有案例,或者执行<testclass>的<testmethod>案例。

有选择的运行测试案例

你可以只执行某个TestCase类,或者只是执行某个TestCase中的某个method。

演示rununit程序的参数含义:


<testclass> <testmethod>



演示通用开关:


/run:<testclass>[.<testmethod>]


将测试案例写在dll中

测试案例同步更新

测试dll内部组件

关于rununit工具

基于dll的单元测试

对比

为dll写测试程序(exe方式)

优点

方便测试案例的同步更新

并且强迫你同步更新测试案例

可测试dll的内部组件

去除了建立新工程的过程(有点麻烦)。

关于rununit工具

用rununit调试你的dll

rununit程序是一个通用的testcaseRunner,可用于执行(或调试)一个dll中的部分或全部案例。

命令行


rununit testcase[.dll] [testclass] [testmethod] [/ndebug] [/pause] [/output:<xmlfile>]


Visual Studio中调试dll




今天,你“单元测试”了吗?

如果你没有,那么我告诉你,你已经落伍啦!

附录

rununit.exe: 参考ksdn中关于该程序的详细说明。

CreateCppUnitTestCase宏: 参考KSRule.dsm(macros for Visual Studio)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: