测试驱动开发技术作为软件敏捷开发中的一个重要组成部分,在软件开发实践中得到了广泛的应用。本质上,测试驱动开发技术是一种软件开发技术,而不是一种软件测试技术,它的作用在于通过测试来驱动开发,以提高软件的高内聚、低耦合程度,改善软件设计质量,减少软件代码中的缺陷率,提高软件开发的效率,提升软件产品的质量。
《航天标准化》(季刊)创刊于1983年,由中国航天标准化研究所主办。以从事航天行业的技术领导和广大的工程技术、科技管理和标准化专业人员为主要阅读对象。期刊以宣传国家和行业的标准化工作方针和政策、贯彻技术民主与争鸣的原则,以严谨的态度开展标准化理论研究,研究市场经济下标准化工作发展方向及工作方法,探讨型号研制标准化及产品三化等的意义和作用,目的是促进航天事业的技术进步和发展、实现国防现代化、赶超世界先进水平。
测试驱动开发技术相对于传统的软件开发流程,是一种开发思维上的转变。它是一种基于目标驱动的软件开发思想,与传统的先编写代码再进行调试的开发流程不同,强调在编写产品代码之前先思考作为用户该如何去使用这个功能,先确定如何去用这个目标,并通过测试代码使目标明确可运行,之后再去思考如何实现这个功能,需要开发人员在用户与功能开发者之间不断进行角色切换,多角度思考。先编写测试代码,再编写产品代码,用测试来驱动开发。
测试驱动开发技术是随着敏捷开发技术不断发展应用起来的,敏捷开发除了测试驱动之外,还包括用户故事、结对编程、持续集成等要素。本文不针对测试驱动开发在敏捷开发中的实践,而是将测试驱动开发技术应用于传统的软件开发,与传统的领域开发流程相结合,介绍测试驱动开发技术在领域应用中的实践。
1 测试驱动开发
本节介绍测试驱动开发的概念及测试驱动开发所起到的作用。
1.1 测试驱动开发概念
测试驱动开发技术是由Kent Beck于20世纪90年代提出并不断发展起来的,基本方法是编写所有产品代码的目的都是为了使失败的测试能够通过。首先编写一个测试,由于它要运行的功能还不存在,所以它会运行失败。然后,编写产品代码使测试通过。作为结果,一个非常完整的测试用例集就和产品代码一起发展起来。软件重构、领域驱动设计、敏捷软件开发与实践等技术或实践均将测试驱动开发作为一个必要条件和实践原则,它们的一个共同特点是均采用迭代开发思想,在开发过程中不断对已有产品进行精化和完善。软件重构关注改善既有代码的设计,从代码层面不断对软件进行优化,使代码结构更合理、扩展性更好,可理解性更强。领域驱动设计关注领域模型与代码实现的绑定,强调软件各个部分的设计应忠实地反映领域模型,与模型相对应,在开发过程中通过不断的重构与精炼去获得和实现深层次的领域模型。敏捷软件开发与实践将测试驱动开发作为一个基础实践,与其他实践结合形成一个完整的迭代开发流程。
1.2 设计作用
测试驱动开发要求在编写产品代码之前先编写测试,开发人员首先必须站在产品代码使用者的角度去思考应该怎么去使用这个功能,这个功能应该提供哪些接口供测试代码来访问,这种思考方式会促使开发人员先从接口的角度考虑功能模块的设计,促进功能模块的接口设计的正确性与合理性,同时会激发开发人员去解除各个功能模块之间的耦合,这样才能够对各功能模块进行独立的测试,形成高内聚、低耦合的软件设计与实现。从一定程度上说,编程就是设计,测试驱动开发可以实现更好的设计。
1.3 文档作用
测试驱动开发的第二个作用是提供精确的功能模块使用说明文档。随着测试驱动开发过程的不断进行,会建立起一套非常完整的测试用例集,该用例集精确的描述了各个功能模块的使用方法,功能模块的使用者通过测试用例可以准确的查看功能模块的接口及其使用方法,明确功能模块需要的前置条件及执行结果的后置条件,更好的理解模块的功能和作用。从一定程度上说,源代码就是文档,测试代码可以提供更准确、可验证的模块使用说明文档。
1.4 测试作用
测试驱动开发的第三个作用是测试,测试集是随着开发过程不断建立起来的,且均是先编写测试代码,后编写产品代码,通过这套完整的可运行的测试用例集,可以随时对产品代码运行测试用例,对开发过程中运行的所有测试实现可重复的自动化的运行,因此从开发人员角度考虑,可以认为产品代码的正确性与测试用例是否全部通过是等价的。同时开发人员工作是否完成的标志从编译是否正确变成了测试用例是否全部通过。
1.5 基础设施作用
一个优秀的软件架构和软件产品的产生,需要结合应用领域不断的进行实践、重构、优化,包括代码级别的重构、设计模式级别的重构、领域模型的重构及软件架构的重构。对一个软件架构或产品不断进行不同级别的各种重构,势必会对已经可以正常工作的软件代码造成很大的影响,引入各种各样的软件Bug,这也是很多开发人员不愿意或没有勇气对已有软件进行重构或调整的原因。而测试驱动开发技术可以很好的解决这个问题,将测试驱动开发产生的测试代码作为软件产品开发的一个重要组成部分与基础设施,一定程度上,软件的正确性与测试是否全部通过是等价的。在重构的过程中不断进行测试,如果因重构引出问题,测试结果会立刻显示出来,由于每一步的重构动作都是很小的一步,且刚刚进行过修改,印象深刻,结合有问题的测试用例,可以很快地定位问题的原因,确保在不影响软件正确性的前提下,软件的各类重构能够有序进行。
2 航天领域应用实践
航天领域作为一个高风险的行业,对应用软件的正确性与可靠性提出了更高的要求,要既能满足航天工程所需的软件需求及其变更,又要确保软件的正确性与可靠性。测试驱动开发技术作为软件开发活动中的一个优秀实践,可有效提高航天领域软件产品的正确性与可靠性。
2.1 工程实践
测试驱动开发的工程实践包括学习测试框架、搭建测试环境、实施测试驱动开发等步骤。测试驱动开发的实践原则是非常简单的,重要的是开发人员要从思想上接受这种模式并通过不断的训练,使测试驱动开发技术真正融入到日常的软件开发活动中。
2.2 学习测试框架
要应用测试驱动开发技术,首先必须学习一些常用的测试框架及测试的方法。目前C++、Java、C#等主流的程序开发语言都有优秀且开源的测试框架,如xUnit系列测试框架支持Java、C#、C++等语言的测试,GTest是一个支持C++语言的跨平台的测试框架,提供了支持测试的各项功能。另外,还需要学习对测试框架的初始化、测试用例的建立与退出、支持各种数据类型的声明和断言。当然,测试框架也不是必须的,在没有可直接使用的测试框架的条件下,自己也可以开发一个简单测试环境,重要的还是测试驱动开发的思想。
2.3 搭建测试环境
原则上,测试代码一般作为一个独立的可运行的测试项目,与产品代码所在项目保持独立。在真正的产品代码开发之前,先把测试项目运行起来,然后通过编写测试驱动产品代码的编写。测试代码项目随着产品代码项目不断发展,形成一套完整的测试集。
2.4 实施测试驱动开发
测试驱动开发的基本的实施步骤是,首先编写一个测试,由于它要运行的功能还不存在,所以它会运行失败。然后,编写产品代码使测试通过。每次编写的产品代码只需要确保测试能够通过。在切换到测试代码的编写,重复此过程。一般测试代码与产品代码的切换非常快,通过“编写测试代码→运行测试失败→编写产品代码→运行测试成功→重构”的循环模式,推进软件产品的开发过程。
2.5 训练方式
要将测试驱动开发技术真正应用于开发实践,使其成为软件开发人员开发思想的一个必不可少的组成部分,需要进行有效的训练和刻意的练习,整个过程可分为三个阶段:第一阶段,强迫自己先写测试代码,再写产品代码;第二阶段,在实践中应用,有时可能会无意识地转换回传统的软件开发流程,直接去编写产品代码,在开发过程中,当意识到这段产品代码还没有编写测试时,应马上停下来,补充相应的测试代码,有意识的不断训练;第三阶段,会自觉的先编写测试代码,再编写产品代码,如果某一时刻直接去编写产品代码,自己会觉得很不舒服,感觉缺少了什么东西或对什么事情不放心,会立刻意识到应该去编写测试代码。到该阶段,测试驱动开发的思想会真正融入到开发人员的开发思维中,形成一种自觉的开发行为模式。
2.6 效率问题
刚开始接触测试驱动开发的人员都会有编写测试会不会降低开发效率的问题。传统的软件开发模式中,编码与调试所耗费开发人员时间的比例一般为1∶3,调试会占用开发人员大量的时间,耗费开发人员的精力。测试驱动开发技术会彻底改变这种传统的工作模式,通过不断编写测试用例、频繁的运行测试,几乎不再需要进行软件调试的工作,即使需要调试,也会很快定位并解决问题,因此测试驱动开发会很大地提高软件开发的效率。
3 结语
本文介绍了将测试驱动开发技术应用于传统的软件开发流程,并详细介绍了测试驱动开发在航天工程领域的应用实践,应用结果表明,测试驱动开发可以有效提高航天软件的开发效率,确保软件的正确性与可靠性,提升软件质量,促进航天软件的产品化。
论文指导 >
SCI期刊推荐 >
论文常见问题 >
SCI常见问题 >