原先我对TDD并没有太多的了解。原因之一,这是Aglie(敏捷开发)方法论的一环,而目前我所经历的专案与团队并没有使用敏捷开发;之二,对于TDD,我一直以为就等于是Unit Testing,只是把写Unit Testing Code的时间从写程式本文后提前至写程式本文前,就这么简单。事实上不然,TDD不单单指的是Unit Testing,事实上也可以用来进行后端的模组测试、整合测试等等。但TDD强调的不是"测试"这件事情,而是"开发"这件事情。为了要做好开发,所以先写好测试程式,这对于某些想改变软体品质的主管或是专案经理来说,看起来好像是个不小的诱惑,但真的做起来,这那么简单吗?
最近几天看了一些讲TDD观念与执行心得的文章,归纳了几个想法,顺便整理一下跟大家分享:
一、要导入TDD,软体的需求必须明确,才有办法让测试程式码开发先行,事实上Agile开发方法论强调的是应变需求的速度加快,但无法应付变化频率太高或是变化幅度太大的软体需求(以Scrum来说,一个冲刺周期建议是一个月,当然还是要看个别专案而定,但原则上不会偏离太大)。测试就是在测程式的"功能",这可能小到是一支程式里面的其中一个Function,抑或是大到系统中使用者会使用到的所有功能,若是软体需求一直变更,变更幅度又非常大,连开发原来功能都来不及了,怎么还会有时间来修改测试程式码呢?
二、网路上看到有人说使用TDD,软体开发的时间被拉长为原来的1.5~1.8倍,听起来主管及PM的心脏要够强,尤其在初期导入TDD的时候,往往会因为专案时程的压力,把TDD三定律先抛在脑后,那TDD的导入注定要失败。
(TDD三定律:(1)没有测试之前不要写任何功能代码;(2)只编写恰好能够体现一个失败情况的测试代码;(3)只编写恰好能通过测试的功能代码)
三、在软体开发工作中,我们常常会碰到,却很少在文章讨论中提到的,是所谓"工作交接"的问题。开发人员来来去去,人员异动,调动专案配合人员,常常在发生,一个交接不好,往往就变成了"历史的悬案",功能原来是好的,某天突然不能用,维护的工程师搞不清楚动了哪里变成这样。如果TDD有落实,可以避免类似的情形发生。当然,前提是要有落实。
四、TDD代表的另一层含义,叫做"自动化测试"。这又是一块诱人的大饼,的确可以软体开发在测试的成本上面大大地降低。不过,TDD本质上是属于白箱测试,一般站在软体品保的立场,还是会建议进行黑箱测试来找出原本未预期的问题。尤其当需要进行使用者介面的测试,如GUI,Web-Based操作等等系统测试,就不合适以TDD的方式来进行。就如同我前面所说的,TDD主要目的是协助开发,而非协助测试。
五、有人说施行了TDD,测试人员就不需要了,我倒不这么认为,理由有下列三点:
1.测试人员在专案组织中多半也负责了软体品保的其他工作,追蹤Defect/Issue处理进度,收集、协调、讨论沟通问题,同时扮演第三方的角色来客观监督审查专案的品质,甚至还可以帮忙PM检查开发人员是否有落实TDD三定律,这部分是开发人员无法取代的。
2.对于测试的设计(Test Design),如Test Cases情境的撰写,测试环境的準备与使用,测试人员还是比开发人员会多一些经验与关注。简单讲一点,像"等价分割法"对于Test Cases的设计有效度是有帮助的,但这是测试方法论,不是开发方法论。太过于要求开发人员执行TDD的时候要懂得Test Cases Design,反而会分散了开发人员的专注力。
3.TDD是功能测试,非功能测试的部分(如安全性测试、效能测试等等)是TDD无法取代的,还是要有人进行这些测试。
看完TDD的一些讨论,我越来越觉得,当整体组织的观念尚未到位的时候,要推动一些新的软体开发或是品保的方法论,是非常痛苦,而且是不容易成功的事情。即使观念到位了,同时还要其他的条件配合(例如客户,专案时程等)。有人说可以不要全面推动敏捷开发,只推TDD,我则认为这样失败的机率很高。