虚拟座谈会:代码测试比率、测试驱动开发及行为驱动开发

发表于:2012-9-26 10:00

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:江辉 译    来源:51Testing软件测试网采编

分享:

  Gojko:这取决于你如何定义TDD和BDD。看起来,在过去几年间,TDD的定义被局限在仅仅作为设计的单元测试。而BDD则变成以实例和业务导向的测试来驱动功能的、涵盖所有开发阶段的方法。根据Brian Marick在《Agile Testing by Lisa Crispin and Janet Gregory》中的敏捷测试象限的定义,TDD应该在第一象限,而BDD在第二象限。我并不完全同意这点,但既然你的问题是什么是影响你采用TDD还是BDD的标准,我假设你对TDD的定义是排除在BDD与其他方法之外的。基于这点,我们分析以下三个方面:

  ● 这是个一次性项目吗?是否为了将技术的不确定性降到最低,从技术层面,帮助团队了解他们最终想要什么?在这种情况下,维护很多自动测试用例集合都是一种浪费,而且极有可能团队真正需要的只是一小部分相关联的简单用户用例。因为我们不清楚技术壁垒,所以编写技术测试可能会是个问题。我可能会选择写一些指导性的测试,而非教条式地为每个设计写一段单元测试。这符合Steve Freeman和Nat Pryce所著的有关《成长性面向对象软件》的大型系统测试。

  ● 项目的复杂度是否由技术所决定?我们是否认同我们所要完成的是技术上的,而非业务逻辑上的风险和不确定性?是否所有项目相关人员都是技术出身,能够读懂代码?例如:搭建Web框架的项目、数据库平台的项目、查询系统的项目、或是云部署平台的项目。众多开源项目都可以归为这几类。如果是这样,那么偏技术的TDD就比较适用了——我会用单元测试工具来驱动业务场景和技术设计。我可能还会在白板上写些例子以求得到普遍认同(BDD的核心概念),但我不会浪费时间把这些例子录入到可执行用例或非技术自动工具(Cucumber)中了。

  ● 项目是否也有复杂的业务逻辑需要讨论,或者存在不清晰的业务需求,需要在不懂编程语言的成员之间沟通的情况?如果是,我将各个击破。先使用实例来探讨业务需求,确保大家对业务有共同认识。然后为这些实例建立规格说明书,并将这些实例录入到诸如Cucumber、FitNesse或类似的自动工具中去。最后,用单元级别的测试来驱动代码的设计。

  Ron:我多希望在过去的半个世纪的开发生涯中,我能够在每个项目中都运用这两种方法。我并没有发明这两种方法,我只是最早接触的那几个人之一。TDD和BDD让我确信,没有更好的方法了,这两种方法也让我的代码缺陷数量大大降低。并且,当我更好地了解到系统或产品该设计成什么样子时,我的设计就更得心应手了。

  TDD和BDD太难被超越了。

  Steve:你需要为你的系统写测试吗?如果需要,为何不在代码实现前就写完呢?这样一来,你就能知道怎么把测试变得更简单。你也并不可能把所有的测试用例一下子都写完,何不边写代码边完成测试用例呢?

  问题:现在似乎有种普遍的认识,认为TDD等同于单元测试,而BDD则等同于验收测试(无论使用的是哪种工具)。你们认为这种说法是否正确?其他类型的测试例如构件测试与系统集成测试 又是如何与TDD/BDD关联的呢?

  JB:我想从两个方面谈这个问题:TDD对我的设计提供了反馈,而BDD则是对我们开发的产品理解提供了反馈。起初,我以TDD作为一种测试技术开始实施,慢慢地我把TDD作为设计手段,再后来把TDD作为一种深入了解产品设计原理的方式。而对于BDD,我则一开始把它作为提醒我从真正终端客户和利益受益者的角度看待产品的一种方法,最终变成改进业务与技术人员之间沟通的一种技巧。你可以看到,虽然测试在其中扮演着配角,却举足轻重。

  我并不把TDD和BDD当作测试技术,我认为测试策略与TDD/BDD是无关的。无论项目使用TDD,还是BDD,还是什么都不用,我都期望从微测试(microtesting)、系统测试和可用性测试的角度来考虑这个问题。

  Dan:这真的是不幸的历史产物。事实上,TDD和BDD都涵盖这两种测试,甚至更多。Kent Beck在极限编程(此后在他的TDD书中)中说到——TDD在不同等级粒度中均能适用,这也契合Nat Pryce和Steve Freeman在《成长性面向对象软件》所描述的。你撰写用户级别的功能测试与低级别的单元测试的目的是相同的,都是为了阐述你希望代码如何表现。TDD的激励作用多过于实际意义:如果你只为了得到更多的自动测试覆盖率而撰写自动测试用例,那不是TDD。类似地,你可以测试诸如并发、延迟、failover或吞吐量等非功能性需求。

  BDD之中用户级别测试与代码级别测试的区别更加明显。用户级别的测试是基于自我澄清和自动化的场景。并且这些构建的步骤可以在其他场景中重用。代码级别的测试也叫做实例(或者规格Spec,虽然我不倾向于这么叫),与TDD相比更接近人的思考方式。时过境迁,有不少不同类别的工具出现。比较有名的有:用户级别的跨语言工具Cucumber,以及代码级别的工具RSpec、NSpec等。我的经验是,我倾向于使用团队喜欢的工具。比如,大部分的BDD源码,我用过时的JUnit与JMock的Hamcrest matcher library编写。最近,我用Python的py.test和nodeunit来写node.js,这与JUnit风格类似,“BDD风格”的框架在两者中均有体现。因此我的建议是,这只是代码,如何实现它由你决定。

  Gojko:同样,这取决于你对TDD,BDD以及其他概念的定义。我对Kent Beck著作的理解是用户测试与单元测试属于TDD范畴。而我对Nat Pryce和Steve Freeman的《成长性面向对象软件》中的理解是TDD包括系统测试,构件测试以及单元测试。我对规格说明书的解释是好的文档会将业务概念拆分,并自动化,以求风险得到控制——如果大部分的风险来自于一个实例,我们则需要验证实例的Java方法;如果风险来自系统,我们则需要对系统进行30次的Web服务运行和100次数据库运行。

  Ron:BDD起源于TDD的另一种描述。而现在,在Chris Matts和Liz Keogh手中,BDD演化成实现产品特征描述与验收测试的方法,这也是我所理解的BDD描述。

  而其他形式的测试,当然也很重要。我特别指出,我们需要把用户体验测试加入到你的测试列表中。关于构件测试和系统集成测试,敏捷项目的最佳方式是使用持续集成(Continuous Integration)。这样,所有分散的构件就能关联起来,集成的系统所能承受的测试也随之增加。通常,这些分类很模糊。我们针对不同事件,在不同的间隔运行不同的测试集,比如:新的类库或构件,或新构建的版本。这样的测试集包含了用以描述单元测试、验收测试等所有的测试用例。 测试的精髓在于,分清什么需要测试,尽量在创建或有变化的时候就进行测试。这就是我们防止代码缺陷和及时发现代码缺陷的秘诀。

  Steve:我可不会做这样的类比,很明显,这是基于对TDD的错误理解。TDD中最基本的问题是“我怎么知道这样是可行的?”——所有的业务和组织都可以这样去考虑问题。

  我并不认为将测试细分成筒仓(silo)会有多大帮助,相反顺畅的测试给团队带来自信,相信系统能够正常运行。

52/5<12345>
精选软件测试好文,快来阅读吧~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号