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