要使用TDD,估计需要先费了以前的“武功”才行。我们不能一上来就质疑、评论TDD,需要先去尝试、去使用、去掌握TDD才行。对任何新事物都应该有这样的态度。James Grenning的培训让我们做了很多UT的练习。但是他倡导的UT,跟我们天天谈的UT不同。根据我这两天的理解,总结一下。
1.在写代码之前写UT是。当然了有人会问,这个测试先行有什么区别。就先后顺序还真没有区别,但TDD还强调:
You are not allowed to write any production code unless it is to make a failing unit test pass.
You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
You are not allowed to write any more production code than is sufficient to pass the one failing unit test.
[注] Bob大叔TDD三条规则
我高亮了重点。一个关键的问题是定义什么叫“足够”,“足够”的测试导致失败,“足够”的代码通过测试?
如果你编写过多的测试,那么意味着你需要花很长的时间来写代码,调试代码,从而让代码通过测试,这不是TDD。如果你编写了过多的代码,那么意味着你多写的代码并没有得到测试。如果去补丢掉的测试,这就违背了TDD 的基本要求,事后补救往往都是借口。而且人是倾向与认同自我的,事后补救往往发现不了自己的问题。
“足够”的衡量依人不同,一个好的判断标准是你不需要去调试,并且马上可以回滚。因为调试就意味着你步子迈得过大,你把事情弄复杂了。回滚意味着我们不会掉到坑中,迟迟爬不出来。理想情况下,编写代码就像行云流水:轻、静、顺。
测试先行与TDD的问题,总结一下认识。
2.重构是必需的。TDD要求我们从简单的、基础的问题着手。意味着代码的实现一定不是完备的、最优的,而是很容易违背DRY原则。我们需要在测试变绿的时候来做重构。这个重构也包括两个方面:
3.代码一直要是可编译、可运行的,并且通过已有的测试。
这可能跟绘画、雕塑不同,它们都是先有一个轮廓,然后逐渐把轮廓细化下去。所有的动作都是从整体着眼,不会先完工一个局部,再去完工另外一个局部。作品的完工往往是这个制品整体接近尾声。这就是艺术,值得精心雕琢,花上数年去追求的东西。
软件开发也可以是一门艺术。但是作为我们现在处的环境来讲,它就是一个工程。工程需要各种平衡,对美的平衡就是一种,工程师是不允许有艺术家一样挑剔的眼光。另一个平衡点就是客户需要可以工作的制品,而不是功能很多,但运行就出错的东西。做到这一点,我们可以确信的是所有编码已完成的部分都是可用的。