在C和C++开发过程中应用测试驱动开发的理念

测试驱动开发和现在流行敏捷开发的是分不开的,测试驱动开发是敏捷开发的一个强有力工具,可以帮助我们从简单的设计开始,逐步地有保护重构设计直至完善设计过程。测试驱动开发是 Kent
提出的一种新的软件开发流程,现在已广为人知,这种开发方法依赖于极短重复的开发周期,面对开发需求,">开发人员要先开发代码测试用例,这些代码实现的测试用例定义了工程要实现的需求,
然后去开发代码快速测试通过这这些用例,这个时候的代码是相对比较粗糙的,只是为了通过这个测试,测试通过以后,这些测试所覆盖的需求就会相对固定下来了,然后随着实现更多的需求,以前实现的那些粗糙的代码的问题会逐步的暴露出来,此时就要用重构来消除重复改进代码设计,因为自动化的测试用例已经框定了相应的需求,这样在代码改进和重构的过程中就不会破坏已实现的需求,实现了安全重构。

从测试驱动开发的流程可以看出来,测试驱动开发仅仅要求一个简单的设计开始实现需求,然后随着软件开发的推进实现有保护重构代码和设计。依赖于 TDD 开发所生成的单元测试用例代码,实现有保护重构是大型的软件开发项目不可以缺少的,代码级别的测试更能有效地提高软件产品的质量。测试驱动开发中的重构过程也是一个使设计逐步完善的过程。 本文的主要目的是使测试驱动开发落到实地,和具体的语言(C++)和单元测试框架结合起来,并用实例展示测试驱动开发的魅力。

测试驱动开发的信条

先开发和设计测试代码,再代码实现通过测试,以测试驱动设计实现,开发和设计的过程,得到了快速的反馈,用这些反馈驱动,改进和重构代码设计,是一个有机的开发过程。按照 Kent 的定义,测试驱动开发的原则是:

不要写一行代码,除非有一个失败的自动化测试案例要纠正。 消除重复的代码,改进设计。

这两个简单的原则,却产生了一些复杂的个体和组的行为,这些隐含的技术行为包括:

运行代码对设计决定快速反馈下,实现有机地设计 必须自己写自己的测试用例,而不是等待别人帮你写测试代码,那样会花费很长时间 必须要有对变更代码快发反应开发环境 组件必须要高内聚、低耦合,以使测试简单化。

两个原则还隐含开发任务的顺序:

红色(Red):写些不能够工作的小测试,这个测试甚至不能编译通过。 绿色(Green):快速编写代码使测试通过,
不用太在意代码质量只是通过测试。 重构(Refactor):消除开始是只是要通过测试的重复代码,改进设计。

红色(Red)-绿色(Green)-重构(Refactor),这个就是测试驱动开发的座右铭(Mantra)。这种开发方式可以有效的减少代码的缺陷密度,减少 bug 的数量,将大部分的缺陷在代码的开发过程中消除,减少了 QA 测试和质量保证的成本。

按照软件工程的说法,软件缺陷和 bug 发现的越早,所需的更正这些缺陷的成本就会越小。所以在软件的开发阶段,采用测试驱动的开发方法,把测试引入到开发阶段,使测试和质量意识融入到开发的过程中,这对提高软件工程质量非常有帮助。 而且在采用测试驱动开发必然要求所开发的组件、接口、类或方法是可测试的(testable),这就要求开发的组件,接口要遵循组件和类高内聚(Highly Cohesive),组件和组件、类和类之间低耦合(loosely Coupled)原则,这种开发方式生成的代码必然会帮助开发者,在不断的有保护重构的过程中,提高软件架构的设计,使日后的软件维护变得有章可循。

测试驱动开发符合敏捷软件开发的精神,在不断迭代过程中,增量地实现软件需求而这一切开始可以从简单设计开始。

单元测试框架比较和筛选

C++技术是一种高级语言,它出现的时间要比 Java 和 C#早得多,但支持像 xUnit 框架的 C++单元测试框架发展起来的比较晚。 C++ 的单元测试框架选择比较多,现在比较流行的 C++测试框架有 Boost Test、UnitTest++、CppTest、Google C++ Testing Framework。 Boost Test,拥有良好的断言功能,对异常控制,崩溃控制方面处理的比较好,也有良好的可以移植性,但结构复杂,不易于掌握。CPPUnit 是开发比较早的单元测试框架,是对 JUnit 的 C++的移植的一种尝试,拥有丰富的断言和期望功能。Google Test C++ 简称 Gtest,是近期发展起来的单元测试框架,对 xUnit 支持的比较好,支持 TDD 的红-绿-重构模式,支持死亡和退出测试,较好的异常测试控制能力,良好的测试报告输出,拥有自动注册测试用例和用例分组等功能,还有和 Gmock 框架的无缝结合,支持基于接口的(抽象类的)Mock 测试-模拟测试。

下表是一个对三种流行 C++单元测试框架的简单比较,Gtest 虽然发展起来的较晚,但丰富功能简单易用,易学,加之移植性较好,是跨平台项目单元测试框架比较好的选择。

表 1.单元测试框架比较

测试框架支持特性 Gtest Boost Test CPPUnit 可移植性 较好 好(依赖于 Boost 库) 较好 丰富的断言 优 优 一般 丰富的断言信息 优 良好 较差 自动检测和注册测试用例 优 良 一般 易于扩展断言 易于扩展 一般 一般 支持死亡和退出测试(Death 和 Exit) 支持 支持 不支持 支持参数化测试(Parameterized test) 支持 支持 不支持 支持 Scoped_Trace 支持 不支持 不支持 支持选择性执行测试用例 支持 支持 支持 丰富的测试报告形式(xml) 支持 支持 支持 支持测试用例分组 Suites 支持 支持 支持 开源 是 是 是 执行速度 快 快 快 基于接口的Mock测试 通过Gmock支持 不支持 不支持
易用性 优秀 较复杂 较好 支持类型化的参数化测试 支持 不直接支持 不直接支持

时间: 2024-11-03 19:18:00

在C和C++开发过程中应用测试驱动开发的理念的相关文章

《重构与模式(修订版)》—第1章1.4节测试驱动开发和持续重构

1.4 测试驱动开发和持续重构 重构与模式(修订版) 测试驱动开发[Beck, TDD]和持续重构,是极限编程诸多优秀实践中的两个,它们彻底改进了我开发软件的方式.我发现,这两个实践能够帮助我和公司降低过度设计和设计不足的几率,将时间用在按时地构造出高质量.功能丰富的代码上. 通过测试驱动开发(TDD)和持续重构,我们将编程变成一种对话1,从而高效地使可以工作的代码不断演变. 问:编写一个测试,向系统提问. 答:编写代码通过这个测试,回答这一提问. 提炼:通过合并概念.去芜存菁.消除歧义,提炼你

基于IBM Rational Build Forge实现敏捷开发过程中的持续构建

在敏捷开发过程中,软件构建周期以及自动化程度直接影响开发的速度和质量.本文结合具体的软件开发项目,描述如何利用 IBM Rational Build Forge 在敏捷开发过程中实现完全自动化的软件构建,产品安装以及单元测试,进行每天持续快速构建,提高开发团队的效率,改进产品和开发质量. 概述 敏捷开发(Agile development)是一种以人为核心.迭代.循序渐进的开发方法,开发周期一般是两星期到四星期.敏捷开发的一大原则是尽早的.持续的交付有价值的软件来使客户满意,交付的间隔时间越短越

iOS开发过程中专门在调试时运行代码的方法

在开发过程中,我们经常会使用NSLog用于跟踪调试,不过在发布的产品可能 并不希望这些调试代码被运行.这里有一个小技巧分享一下. 在编写代码时可以使用如下方式: #ifdef DEBUG< // Debug 模式的代码... #else< // Release 模式的代码... #endif 其中的DEBUG是在Xcode默认的工程中已经定义好的,也可以根据自己的实际情 况添加其他常量定义. 在Xcode中,选择导航区域左侧顶端的根节点,然后选择Project/Build Settings,在

陈榕:操作系统开发过程中遇到的困难及解决方法

[中云网 消息]5月29日,以大力发展并推动北京科技原创能力为宗旨的"2013中国·北京(国际)开源大会"在北京新世纪日航酒店隆重开幕.本次大会由北京市经信委指导,中国软件行业协会主办,中云网承办,并得到了中国云产业联盟.中关村云计算产业联盟.天云趋势等单位的大力支持.大会以"开源中国  原创北京"为主题,通过丰富前瞻性的思想盛宴,力争让北京在世界科技发展新趋势下占据主动地位. 上海科泰华捷科技有限公司董事长陈榕 [中云网 配图] 上海科泰华捷科技有限公司董事长陈榕

移动-大家在开发过程中如何碰到PM提出的需求明显不合理,怎么解决?

问题描述 大家在开发过程中如何碰到PM提出的需求明显不合理,怎么解决? 对我们做移动开发的应该都碰到过这个问题,产品经理不断改需求,有些需求甚至是明显不合理的,这个问题是怎么解决的?应该如何与产品人员沟通?(好像非移动开发也经常有这样的情况) 大家都来说说是怎么解决这个问题的? 解决方案 我觉得这事没有什么可质疑的. 产品经理毕竟是专业的,对产品的设计也是从用户体验上讲的. 当然,如果产品上的设计到开发这里需要对架构进行大调的话,应该和产品经理商量一个中间方案来. 不排除一些产品经理确实很外行,

hibernate开发过程中的问题

问题描述 hibernate开发过程中的问题 在利用Servlet处理增.删.改.读的功能时,有些函数看不懂,能不能解释一下,尽量详细一点.1. //显示添加页面 protected void initAdd(HttpServletRequest request HttpServletResponse response) throws ServletException IOException { List<Cat> catList = baseDAO.list("" sel

快速原型开发模式在实际开发过程中的应用

[摘要]本文以作者的实践开发经验为主线,从理论和实际的角度探讨快速原型开发模式在实践开发中的应用,并从软件开发的各个角度.各个时期剖析快速开发模式的优缺点和应该注意的问题. [关键字]软件工程.开发模式.快速开发.软件开发.原型模式     快速原型开发模式的基本思想是在系统开发的初期,在对用户需求初步了解的基础之上,以快速的方法先构造一个可以工作的系统原型.将这个原型提供给用户使用,听取他们的意见.然后修正原型,补充新的数据.数据结构和应用模型,形成新的原型.经过几次迭代以后,可以达到用户与开

swing 开发过程中遇到的奇葩问题

swing 开发过程中遇到的奇葩问题 1,实现Ctrl+Tab 切换页签的功能 但是在实际开发中遇到了问题,切换的时候,预期是切换到序号33的页签,结果切换到了序号34 的页签. 后来发现Ctrl+Tab是系统的快捷键,与程序实现功能混淆,导致错乱. 最后就在程序中使用Shift+Tab 快捷键 Java代码   if (event.getClass() == KeyEvent.class) {                               KeyEvent kE = ((KeyE

后端开发-在开发过程中,用List&amp;amp;lt;Map&amp;amp;gt;好,还是List&amp;amp;lt;POJO&amp;amp;gt;好?

问题描述 在开发过程中,用List<Map>好,还是List<POJO>好? 或者说这两者的分别适用在不同的地方~ 或者说这两者的分别适用在不同的地方~ 解决方案 List> 优点: 省略了POJO类,返回字段不受POJO类的限制了. 缺点: 看起来不明朗,没有文档的话根本不知道MAP里面有什么属性. List 优点: 从类名就可以知道是什么类型的数据,方面代码里面操作属性. 缺点: 需要写POJO类,并且维护字段的增减. 不过通常情况还是会使用List. 解决方案二: 一半