Test优先驱动开发中 常见问题与对应思路

一.什么是测试驱动开发。

    引用维基定义。

测试驱动开发(英语:Test-driven development,缩写为TDD)是一种软件开发过程中的应用方法,由极限编程中倡导,以其倡导先写测试程序,然后编码实现其功能得名。测试驱动开发始于20世纪90年代。测试驱动开发的目的是取得快速反馈并使用“illustrate the main line”方法来构建程序。测试驱动开发是戴两顶帽子思考的开发方式:先戴上实现功能的帽子,在测试的辅助下,快速实现其功能;再戴上重构的帽子,在测试的保护下,通过去除冗余的代码,提高代码质量。测试驱动着整个开发过程:首先,驱动代码的设计和功能的实现;其后,驱动代码的再设计和重构。

二.实际开发碰见的问题

    很多同学在学完了test优先开发后,往往第一次实践是严格按照开发顺序来的,先写spec,再写测试,再实现代码。

    但是,第二次开发可能就没这么来了,或者没那么严格了,可能是写完spec后,先写代码,再去写test,也可能spec也没写直接去实现代码。最后要么写出来的测试样例不能充分证明程序正确性,没有严格划分等价类与多种测试策略,变成低效的“白盒测试”,要么就是写出充满风险的不可信代码,导致前功尽弃,开发混乱。

那么为什么会出现这样类似的困境呢?

实际上同学之所以会像上面提及的那样改变开发顺序不是没有道理,往往是下列两种情况。


    第一类,前期工作没做好。

    很多同学对spec 的概念和模式不熟悉,对这种通过特定形式描述自己要开发内容的手段不理解。导致写的spec并不好,起不到应有的指导作用。于是导致同学对这个要开发的程序认识很模糊。接下来根据顺序他写完spec后需要写一个测试自己类的test,但是困于对开发对象的认识不够清晰,这一步根本做不了。

    那怎么办呢?只有先去实现要写的具体代码,在不断实现中思路渐渐清晰后,才能去写test,但是为了证明自己实现的思路是没问题的,他需要边写代码边debug,确保最终能做出来。那么当他这么一路做下来后,能看见的bug往往已经解决了,看不见的bug也不知道会藏在哪里,无法通过金字塔框架用底层去证明顶层正确。所以到写测试时已经不知道该怎么办了。程序无法被验证完全正确。


    第二类,认为test驱动开发过程写test和spec部分过于繁琐。

    相对写一个优秀的test,可debug的代码操作起来更简单,甚至有时候能一眼看破,故写完spec后顺手就写上了对应的代码。导致写test前就已经把代码实现了并且没有已知bug,于是test工作变的冗余繁琐,于是有的开发者为减少冗余可能实现测试时就不是按照spec来的,而是参照已经写好的代码来的,只是重复一下自己的确认过程,导致测试被简化,许多问题可能无法被发现。

    以上两种情况都没有严格的按照test驱动方法的顺序或细节去实现,于是往往test设计与检验环节出现一定的问题,test起不到一个代替客户检验程序的作用,程序的正确性也无法得到验证。


三.解决的办法

    我个人觉得,如果要让开发者做到能比较好地接受Test驱动开发流程,自觉地按照步骤来做,需要开发者理解两点。

    一,“端正态度”——认清开发过程的核心与次要。

    开发过程中,约束规则的确定和测试的构建才是开发的核心内容,实现代码只是次要工作。

      给出一个合理的架构等价于给出了一个可行的方法。它将所要涉及的操作全部描述清楚,剩下的只需要按照它的要求来实现就可以了。这时候写代码的工作是任何一个会写程序设计语言的人就可以做的简单操作,他只要机械地执行要求即可。

      给出一个充分的测试环境等价于给出了一个判断代码实现是否有效的方法。它可以轻易证明代码是否可行,将验证代码变成傻瓜操作。同时它可以从逻辑上证明程序安全正确。

      所以以上两个工作其实都是实际去开发代码的前驱工作,优秀的spec和测试会让代码开发变得简单而迅速。然而不合理的架构和测试会恶化开发过程,盲目的代码开发只能写出存在风险,未知的,不可靠的代码。对于客户,这种不可信代码,与垃圾无异。

      所以如果我们有10份的时间精力,我们应当要投5份给spec相关工作,投4份给测试工作,只把最后的一份用于傻瓜般的代码开发。

      二,“突破束缚”——学习规则,驾驭规则。

      在写低层ADT的时候,方法前后置条件怎么描述才合理?写test strategy到底该不该描述一个感觉直观到像废话的规则呢?rep感觉没有限制,那rep invariant那里填什么呢?......

    你是否碰见过这样的问题,这些老师课堂上没讲,百度上又不好查的规则性问题是否给你带来过困惑?

    实际上,如果一个程序员在测试阶段和构建spec阶段总是被类似的规则问题困扰,那么他心中一定会有种被这些“条条框框”缚住手脚的痛苦,从而不愿意采取正确的开发步骤。因此我们要解决这个问题,就需要学习这些规则,从而驾驭他们。

    这些“文字规则”的设计本意都是辅助你去更好地规避风险完成你的开发的。所以并不会因为你的spec格式写的不好看而导致你开发失败,也不会因为你把不需要的文字辅助留作空白而导致程序崩溃。这些只是帮助你设计架构时考虑更全面更细致。所以你完全可以在这些硬性文字辅助要求的基础上结合自己开发风格,给出一种你的描述。一切只要能描述清楚即可。

    任何一个人都能说出上面的一段话。

    但是问题往往就在于我们不知道哪种描述是大家都看得懂的,哪种描述是又简洁又清楚的。

    故从实际出发为了解决这个实际问题,我强烈建议大家去翻看java SDK中的源码,尤其推荐自带ADT的各种源码(Integer,String,Boolean,Char......),当你去一个个翻出来看的时候,观察大佬们怎么实现每段的文字规则描述后,自然就会了。唯有多练才能驾驭规则。代码如此,文档亦如此。

    附上查看源码教程:https://blog.csdn.net/sinat_21843047/article/details/80291766

你可能感兴趣的:(Test优先驱动开发中 常见问题与对应思路)