需求文档可测试化

大家接触到的需求文档是什么样子的?我从来没有看到过一份我满意的需求文档。都是word格式的,文字加上图片说明。文字都是简单的陈述句说明,比如:用户名不能重复。简明扼要,是不是?是你妈个逼!sorry,我爆粗口了,但这种文档真的会让你疯掉的!

你觉得这是一个很简单的需求,是吧?然后你就噼里啪啦的开始编码了,20分钟搞定,踌躇满志,小case啊!

然后噩梦就开始了。

第一次验收。发包方的眉毛皱了起来,“嗯,其实我想的是那种:当用户把用户名输入完成之后,能立即显示该用户名是否重复,而不用点击提交之后才显示这个结果,你看XXXX网站就是这样的”。OK,Ajax效果是吧?好呢,我改。感谢asp.net mvc,有现成的Remote实现,20分钟,收工,over!

第二次验收。发包方有点不耐烦了,“你这个还是不对啊!你看我给你说了XXXX网站,如果这个用户名不重复的话,要打个勾啊;错了,打个叉,再显示‘用户名重复’的提示啊……”。你有没有想哭的感觉?我忍,含着泪,找个勾勾叉叉的图片,再改。

第三次验收。发包方终于笑了,“不错不错!”你心里一块石头落了地。但这发包方思维很严密,他突然想到一个问题,“你说,假如两个用户同时注册,用的是同样的用户名,这个用户名也是以前数据库里没有的。所以页面输入的时候,肯定是显示用户名有效,是吧?所以他们都可以提交,但他们用户名又是一样的,都提交了就重复了,这时候会发生什么情况?……”你仔细的想了想,是不是觉得晴天霹雳天旋地转?

这只是一个非常非常简单普通的需求,都可以演化出无数种具体实现,更何况其他你可能从来没接触过的复杂需求?你作为一个程序员,只是觉得苦逼郁闷或者还得赶工加班;但对于公司来说,这就是个大麻烦了:工期延误、费用增加、信誉破产……这时候该追究谁的责任?我们可以设想这样的对话:

发包方向你们公司老大抱怨:“张总,你们这个项目都延期好几次了,我不好交代了呀!”

公司老大张总叫来项目经理:“这个项目怎么回事?赶快去催一下。”

项目经理找到你:“怎么一个功能做这么久?你是怎么搞的?”

你:“我怎么搞的?需求改了N遍了!我还想问你是怎么定的需求呢?你看……”

项目经理找到公司老大:“张总,这个客户的需求变了啊!一直改需求,我们……”

公司老大找到发包方:“这个刘总,这个项目你们改了需求啊!不光这个工期不行,费用也得考虑考虑啊,呵呵!”

发包方就炸了,“还要加钱?你们这些个奸商!合同不是写得好好的,一口价……”

“不是改了需求么?”

“我哪里改?就不过‘用户名不能重复’啊,我改成了‘用户名可以重复’?”

“不是。我们最开始以为……,结果……”

“你们为什么最开始不提出来呢?你们是专业人士,你们应该把这些问题考虑到的呀!还亏得我们思虑周全,我们业余人员都能想到的,你们怎么就想不到呢?你们怎么样的一个业务素质?……”

(程序员同学,说句题外话,老板在外面受的气不是你们所能想象的。你以为他们在外面吃喝玩乐好不潇洒,他们实际上就一个“三陪”而已,陪吃陪喝陪笑,不比做小姐的好到哪里去!都是给你们“背黑锅”“揩屁股”啊。)

就事论事,这件事的责任还真赖不到发包方。他的需求最多算是“不明确”,你不能说他“变更”了需求。但是,不明确的需求你接受了,责任就转移到你的身上了。退一万步讲,你是“专业人士”,你真的应该考虑得比发包方周全。

所以,你观察周围经验老到的程序员,他们拿到这个需求是不会立马动手敲代码的。他们一定会想一想,多问几个具体细节,觉得没有问题之后,才开始动手。所以他返工就少,他就是可以不加班,这就是人家的本事。

但是,正如我反复强调的,架构/管理的目的,应该是通过一种制度一种流程来避免上述问题,而不是靠个人技巧经验。追根溯源,解决这个问题,就应该“明确需求”——也就是说,需求不能这样懵懵懂懂大而化之,必须相当的明确清晰,具有唯一性。怎么实现?需求文档可测试化。或者你可以理解为:把需求文档像测试文档一样写。比如,上述需求就变成:

  • 在注册页面
  1. 输入用户名xxxx,移出焦点,页面不刷新,显示图标“叉”和错误提示:用户名重复
  2. 输入用户名yyyy,移出焦点,页面不刷新,显示图标“勾”
  3. ……

这份需求/测试文档,交发包方审核确认;之后验收,就严格按该文档逐项进行,所有测试通过,验收合格。如果需要加需求,一般都得加测试;加测试,那不用说,我们就来谈谈时间费用的问题。