通过测试驱动开发软件体系结构的改进
1.问题和动机
尽管经历了一个半世纪的进步,软件构造行业仍然显示不成熟的迹象。专业的软件开发组织以可预测和可重复的方式继续努力生产出可靠的软件。虽然各种各样的开发实践主张,可能会改善这种情况,开发人员往往不愿意只根据传闻采取新的、可能更好的做法。这种做法的有效性的实证证据很少或确凿并且采用新的做法是耗时、昂贵和有风险的。
测试驱动开发(TDD)是一种新的方法,它提供了显着提高软件的构造状态的潜力。TDD是一个严格的软件开发实践,侧重于软件设计首先编写产品代码自动化单元测试,随后在短期频繁的迭代产品代码. 而软件体系结构的有机增长,TDD使软件开发人员的注意力关注于软件的界面和行为。
本研究采用实证的软件工程技术研究TDD来生产在可重用性、可扩展性和可维护性方面比传统的测试更好的软件设计,此外,本研究探讨了教学方法的影响和结果。
如果TDD证明,以较低的成本可以提高软件质量,如果学生可以从早期学习和受益于TDD,那么这个研究可以对软件构造的状体产生重大的影响。软件开发组织将认识到TDD的好处是在于设计和测试的方法,他们将会被说服在适当的情况下采用TDD。新的教材和教学资料可以写应用本研究开发的测试驱动的学习方法。由于学生学会采取更严格的方法和TDD开发的测试驱动的方法,,他们将会把这些带到专业软件构造中,提高软件构造的整体状况。
2.背景及相关工作
TDD获得了最近关注,因为他的极限编程(XP)敏捷软件开发方法。尽管TDD已经零星地以各种形式被应用了数十年[12],但最近才提出可能的定义。虽然有些XP实践像结对编程享有重要的研究,但TDD的拥护者主要依靠事实证据来证明TDD的优点。
2.1 TDD研究行业
一些评估研究着眼于TDD作为一种测试实践,以消除缺陷。TDD的三个实证研究,在至少涉及4个不同的公司的工业环境中进行着。这些研究主要是以检查缺陷密度来衡量软件质量的,尽管一些调查数据表明,程序员认为TDD可以提升简单设计。在乔治的研究中,程序员关于TDD的体验是从新手到专家的多种多样的,而其他的研究涉及的程序员刚接触TDD。这些研究表明,程序员使用TDD产生的代码比由相应的对照组产生的代码多传递18%到50%之间的外部测试用例。该研究还报告了使用TDD可以花更少的时间调试开发的代码。而且他们还报告说,应用TDD对程序员工作效率最低程度有16%的影响。换句话说,应用的TDD有时比不使用TDD花费更长的时间。在这个用了16%以上的时间的情况下,有人指出,对照组写的代码也比TDD试验组少得多。
2.2 TDD在学术界的研究
五个研究在学术环境中进行来报告实证结果。当提到软件质量,出了一个以外所有的实证研究专注于TDD的早期发现缺陷的能力。五项研究中的两个报告显著改善了外部软件的质量和程序员的工作效率。一个研究报告了编写的测试数量和生产力之间的相关性。在这项研究中,使用测试先行的学生写了更多的测试,并显着提高了工作效率。所有五个研究相对较小,只涉及一个学期或更少。在所有的研究中,程序员很少或根本没有以往的与TDD有关的经验。
2.3 TDD与设计
作为极限编程的最佳实践的一员,TDD常伴随着敏捷软件开发过程。很多敏捷流程在重要的编程前拒绝一个全面的设计步骤而倾向于一个较小的构造草图之后迅速地编程。在这样的过程中,软件设计和可能架构作为软件的增长被允许出现。程序员在编程的时候做分散的设计决策。
TDD在这种紧急设计中是必不可少的策略,因为之前的代码编写测试时,程序员的思考和决定不仅在软件的界面(类/方法名称,参数,返回类型,并且抛出异常),而且在软件的行为(预期结果给出一定的输入)。据XP和TDD先锋沃德·坎宁安,“测试先行的编程不是测试技术”。 事实上TDD的各种名称包括测试编程、测试驱动设计和测试优先设计。TDD的驱动主要关注TDD如何通知和指引分析,设计和编程的决定。TDD假定软件设计是不完整的,或者至少是非常柔软和开放的进化改变。实证研究主要集中在TDD通过发现和消除缺陷作为改善外部质量的测试技术。然而,并没有为这个工作研究更广泛的TDD的功效,也没有研究其在试点研究之外的内部设计质量的影响。此外,没有实证研究检验了适当的位置或教学技术引入TDD的本科课程。
3 独特的方法
这项研究是第一个综合评价TDD如何影响整体软件架构的质量不仅仅是缺陷密度。经验的软件工程技术在可重用性、可扩展性和可维护性方面应用到评估TDD比传统的测试方法来生产更好的软件设计。
此外,这项研究做出了重要的教育贡献。所谓的“测试驱动的学习”的新的教学方法介绍了结合自动化测试的教学。该研究表明,本科计算机专业的学生可以学习如何运用TDD,并审查TDD在什么时候在课程是最好的选择。
3.1实验设计
这个实验的目的是为了评估内部质量、程序员的工作效率和程序员的看法来比较迭代测试优先的编程(TDD)和实验最后编程。一系列同步实验是在三个本科计算机科学课程,一所研究生软件工程课程,以及一个财富500强公司进行。本科课程的研究同时进行CS1 / CS101(计算机编程1),CS2 / CS102(计算机编程2 /数据结构),和SE / CS391(软件工程)。此外,与该公司进行了案例研究分析以往的项目。
每个研究程序员完成自己的编程经验和对软件测试和设计的观念的预实验的调查。程序员在每个实验中分成平衡控制和研究小组,接受每门课程的制约。
本科程序员被教导编写自动单元测试,集成课程主题使用一种称为测试驱动的学习(TDL)的新方法。该TDL方法包括通过建模与自动化测试实例定期的单元测试的讲座和实验指导。最常见地,在调查中输出语句被替换为自动化的单元测试,来演示接口和代码的所研究的行为。研究生和专业程序员们被给出比较集中的指令TDD,并采用自动化单元测试框架。控制和研究组完成了同一套实验室和训练上的测试,编写单元测试,并使用自动测试框架。指令给出了测试优先和迭代测试的两种开发方法。
学生被要求完成一个或两个编程任务。研究小组被要求使用测试驱动开发技术,而对照组被要求执行迭代测试开发。在早期的课程那里被要求两个较小的任务,第二次任务建立在或重用的第一次任务的重要的部分。
在第二个项目开始的时候,学生们被提供了一个第一个项目的解决方案,该方案包括一个全套的自动化单元测试。在第二个项目,学生可以选择来构建自己的解决方案,或提供的解决方案。
学生们需要跟踪他们花在编程项目的时间。在每个实验结束时,程序员被要求完成一份调查表明他们对测试和测试驱动的开发态度。对学生考试,课程成绩进行比较,以确定是否测试驱动开发和学习成绩之间存在任何关联。
下学期,无论是控制组还是研究组的学生的样本,都将被再次检查,以确定在课程编程作业中自愿使用测试驱动开发。来自CS1的学生将会在CS2中被检查。来自CS2的学生将会在SE课程中被检查。来自SE的学生将会在随后的课程中被检查,如果他们有很多报名一个常见的编程基础课程。
3.2正式的假设
有几个假设被检查。表1给出了形式化的假设。依次逐个讨论这些假设。假设P1认为是否测试优先(TDD)的程序员比迭代测试的程序员更有效率。开发时间,每个功能的特征,以及功能的每行代码都将被检查。
有消息声称,测试优先的程序员持续编写大量的测试代码。我们的第一个假设T1检查是否测试优先的程序员比迭代测试的程序员编写更多的测试。T2增强T1通过检查测试优先的程序员写的测试是否比测试测试程序员写的测试存在更多的产品代码(测试覆盖率)。T2的基本原理是,更多的测试可能只是更好,如果测试多运动或分支生产代码行。
假设Q1测试是否测试优先的代码的内部质量高于迭代测试的代码的内部质量。认识到并不是所有的代码可以被包含在自动单元测试,假设Q2认为是否测试优先的方式开发并被测试覆盖的代码的内部质量高于也是测试优先的开发方式,但没有被测试覆盖的代码。在理想的情况下,这种假设不能被检查,因为所有测试优先代码都将被单元测试覆盖。然而,现实情况是,程序员很少会达到如此高的测试覆盖率。
最后假设O1、O2表达程序员对测试优先方法的意见。假设O1检查是否所有的程序员,他们是否使用了测试优先的方法,认为测试优先是一种更好的方法。假设O2更具体检查是否试图测试优先的程序员更喜欢测试优先的方法,而不是迭代测试的方法。
4.结果与贡献
一个广泛的分析的软件生产的实验正在进行。内部质量是有些主观,措施很容易出现很多争论。然而,许多内部指标确实存在,能够提供对有关软件设计的质量的洞察力,或者至少缺乏高质量的软件。五十多个结构和面向对象度量被收集,目前正在被统计分析。在每个实验里,通过方差分析和配对计算来确定测试优先和迭代测试的不同之处。设计质量的主观措施也被评估。虽然分析不完整,但一些早期的研究结果还是可以在这里报道的。