虚拟座谈会:代码测试比率、测试驱动开发及行为驱动开发
作者:网络转载 发布时间:[ 2012/9/26 11:05:15 ] 推荐标签:
而其他形式的测试,当然也很重要。我特别指出,我们需要把用户体验测试加入到你的测试列表中。关于构件测试和系统集成测试,敏捷项目的佳方式是使用持续集成(Continuous Integration)。这样,所有分散的构件能关联起来,集成的系统所能承受的测试也随之增加。通常,这些分类很模糊。我们针对不同事件,在不同的间隔运行不同的测试集,比如:新的类库或构件,或新构建的版本。这样的测试集包含了用以描述单元测试、验收测试等所有的测试用例。 测试的精髓在于,分清什么需要测试,尽量在创建或有变化的时候进行测试。这是我们防止代码缺陷和及时发现代码缺陷的秘诀。
Steve:我可不会做这样的类比,很明显,这是基于对TDD的错误理解。TDD中基本的问题是“我怎么知道这样是可行的?”——所有的业务和组织都可以这样去考虑问题。
我并不认为将测试细分成筒仓(silo)会有多大帮助,相反顺畅的测试给团队带来自信,相信系统能够正常运行。
问题:一直以来,TDD被公认为是一种(代码)设计准则、测试准则或沟通工具。然而,在TDD方法中,作为这些准则和工具的目标会如何影响设计?在测试方面,TDD现在与未来的价值又是怎样的?
JB:我认为这很大程度上取决于方法的实践者。当我实践TDD的时候,发现有价值的部分是测试规范这块,这可能是因为我期望在这个方面有所提高。而只有当我的错误数大幅度地减少时,我才注意到TDD是如何帮助和指导自己改进设计。在你实践TDD的时候,所有这些都指向对测试的当前价值的个人感受:你可能期望从其他测试中获益。
我觉得测试的当前价值远比未来价值要高得多。虽然从未这样试过,但我曾经打算在几个月后把测试都扔掉,仅当我需要改进某些东西的时候才去重写测试。
我从未在不是我编写的测试上获益,我也不认为这会对我所工作的项目有什么样的帮助,或是对TDD实践者的基本规范有什么样的贡献。对此我有所顾虑,好象合同工走进要装修的房间,然后对之前的装修出言不逊。
我曾经宣称, TDD风格的测试会起到变更探测器的作用(引用Cem Kaner的术语),用来减少代码变更的代价。我也听到过有人像我这么宣称。尽管没有仔细地度量过,但的确见识过TDD所带来的益处。我甚至听说有人宣称,这些测试可以为从未了解系统和API的人,讲述清楚其中的内容。对我而言,这些益处仍旧是理想化和理论上的。
Dan:TDD是一种设计规范,每样东西都有两面性。在 “测试驱动”这个词组中,“测试”这个词很不幸。 你所写的用来描述行为的实例并不是测试,你所写的代码也只是简单的实例。这些实例只有当与类似持续集成等实践联系在一起时,才成为一套的回归测试。但这些无法代替测试的需求,特别是代替类似Brian Marick和James Marcus Bach所倡导的有技巧的、直接的探索性测试。TDD测试的另一个特性是它的决定性。在回归测试中,这是一个优势,但在发现阴暗角落方面(译注:指不易发现或重现的Bug/Defect)做得却不怎样。随机化的测试技巧能够帮复杂的系统找出许多细微之处,然后你可以利用TDD逐个解决。Haskell和Scala的QuickCheck工具是个很好的例子。
关于沟通,这是TDD的主要目的之一。特别是在你需要向其他程序员讲述你的代码意向的时候。在文章《Introducing BDD》中,我描述了有含义的命名方式对测试起到了多么大的帮助。否则,你无法得知你的测试用例失败时所揭示的真相。你必须能够像读故事一样地去理解TDD测试用例,而出色的测试命名则决定了功能文档的易用程度。
Gojko:我认为答案总是位于这些因素的平衡点上。为了将TDD作为一种规范,我们必须找到一种方法来完成所有事情。好的单元测试,能够指引设计。但也必须能够帮助我们缓解关键技术难题带来的风险,并且告诉人们设计的代码应该怎样表现。
Ron:TDD会用到测试,但不仅仅是测试而已。它是我们开发系统的方式,是所有测试和程序的骨架。TDD以及其他相关实践让我们逐步地、一个特征接一个特征地开发系统。从始至终,它保证了代码的活性,以及可塑性。这让我们更清楚地了解我们究竟完成了什么,也让产品负责人或管理者清楚下一步要做什么,不论是通过揭露代码满是缺陷,或者设计是错误的,或者我们不能太快地改进。这也极大地减少了在项目后阶段才了解到坏消息的可能性。
我不认为这些目标是“独立的”。好的软件开发,需要整合很多想法,也需要我们平衡很多目标。我们并不想放弃这些,相反,我们希望能够找到一种方法服务于所有的目标。而这一切,让开发产品变得更快捷。
Steve:当发觉沟通决定着其他方面的结果时,我必须强调所有级别测试中的沟通因素。例如:如果我致力于把一个测试用例写得可读性很高,这真的也能帮我发现对象引用的不恰当。 我见过很多团队陷入过维护性很差的测试用例的泥塘,而从拖累了整个进程。特别是在新的理解或概念出现的时候,你必须像对待生产代码一样(甚至超过)谨慎地对待测试代码。
问题:关于单元测试、集成测试以及验收测试比率的自动化以及相应的维护成本,有哪些准则可以告诉大家?
JB:在团队实践TDD一到两年的时候,我不停地接到团队的消息,向我倾诉测试成本与收益的不平衡。每次这种情况发生,往往是因为团队尝试用较大的测试集(集成测试,系统测试以及端到端测试)去检验较小的事情(独立对象的具体行为)。这往往会导致更大的测试套件,更频繁地运行测试套件(一个失败意味着23个测试失败),也会降低程序员维护测试用例的信心和兴趣。这样的测试,反而会给项目带来负面影响。
在这种情况下,我建议为微行为编写微测试,然后合并微测试。契约式测试是通过连接相邻层(adjoining layer)的接口,来检查这个层,不会再深入。这意味着从集成测试及系统测试转移到检查我所指的“基本对错”上——例如:在无限的时间与空间的条件下,这个对象是否能得到正确的计算结果?我所说的“集成测试是骗局”是这个意思。

sales@spasvo.com