Contents

其实写这个项目的初衷是想实践一下TDD开发,因为自己刚看完一本<<Test-Driven Development with Python>>,以前只是了解一点开发测试,看完这本书感觉这种敏捷开发方式非常适合我,自己完整写过一些小项目,但是大项目经常由于各种代码框架,代码规模搞得最后成了烂项目,而且关于TTD一些建议比如YAGNI(You ain't gonna need it)(你不需要这个)对于你对项目的规模有一定的控制.写这篇博客一方面将我开发hookmanTDD开发经历告诉大家,一方面希望更多人了解TDD开发,换一种开发方式,或许能让你找回编程的乐趣.

##引言

当然网上有些人对TDD测试开发嗤之以鼻,认为开发过程中不应该由测试驱动,应该先把所有的核心都先完善,最后在来完成项目.

在这里我想说一点我的看法,测试驱动是一种从核心到细节的开发方式.

用画一个人来打比方,给你一张白纸,TDD要求你先画一个躯干,这个首先要有个人样,当我们想画一个奔跑的人时,TDD要求你得给他再画两条裸腿,然后这两条腿怎么摆才能控制平衡,这两条腿穿什么鞋才比较生动,要接下来你慢慢测试考虑.

而我们传统的开发方式,是先从局部到整体,这种开发方式适合于小项目,而且像一个流水线出来的产物,比如说web开发,我们知道下一个要做的是视图层,然后模型层.但是这种开发方式不适合开发比如说一个新的软件,假如我们用传统开发方式,除非leader的掌控力非常好,一个越来越臃肿的项目很难坚持到最后,因为我们在项目完成的时候才能让项目真正的运行起来,在完成的过程中我们很容易迷失最后将项目烂掉.

而且我比较欣赏TDD开发的一个主要原因就是他同linux推崇的那种简单的软件开发文化很默契,我们在让我们测试通过时候,我们感觉在:欺骗自己”.

举个例子:

比如我有一个比较两个值谁大谁小的函数

def my_max(a, b):
    pass

我们写一个单元测试

Mytest(unittest.TestCase):
       test_my_max(self):
           m = my_max(1,2)
           self.aseertEqual(m, 2)

我们运行这个测试肯定失败,然后我们开始”欺骗自己”让测试通过,修改my_max

def my_max(a, b):
    return b

再运行测试,通过了,ok,”欺骗成功”,但我们用脑袋一想就知道,不行这个代码不对,但是咋办”测试通过了”,修改测试.

Mytest(unittest.TestCase):
        test_my_max(self):
            m = my_max(1,2)
            self.assertEqual(m, 2)
            n = my_max(2, 1)
            self.assertEqual(n, 2)

这下测试又通不过了,我们想要的功能就在一步一步测试拖动中慢慢实现,我们尽量用最简单的代码通过我们的测试.

看到这里有些人会认为我很傻,明明可以用两行代码(不能用系统函数max)

def my_max(a, b):
    if a > b: return a
    return b

轻轻松松通过测试,但是这反倒是TDD非常不推崇的,你一次走了太多步,你让你的代码跑到Test前面去了,其实很多程序员都会写测试,但是他们的测试很多都是基于代码的,当一个大功能实现的时候才开始测试,这个时候你会发现很多你的隐藏bug就藏在你一大堆代码里面,所以有些人为了排bug一行一行删代码来debug.

诚然很多时候我们感觉我们能毫无bug的完成一大段的代码,但是我们不能保证100%正确,而且或许今天能行明天就不行了,TDD推崇测试山羊精神,想象一只山羊行走在陡崖峭壁上,他只能走一步停一步,我们写代码也一样,我们前面是陡崖峭壁,我们不能保证我们下一步就不掉坑里,所以我们要学习山羊精神一步一步.

接下来关于TDD开发一些详细经历,我会每天抽出一点时候写.

Contents