10 月,开发者不可错过的开源大数据大会-2021 WeDataSphere 社区大会深圳站 了解详情
写点什么

试验驱动开发——“后敏捷”之道

2010 年 3 月 07 日

测试驱动开发(TDD)和行为驱动开发(BDD)现在已经成为广泛应用的软件开发技术。然而,仅仅遵循BDD 和TDD 还是可能导致丧失业务机会,甚至可能对业务产生负面影响。TDD 和BDD 有两个无法回答的问题:如何衡量应用的使用状况?如何得到客户的反馈?

传统的用户调研方式并不一定完全具有说服力,可能要占用应用提供者和客户很多时间,而且会受到偏见影响。 Nathaniel Talbott 在 RubyConf 2009 大会中的演讲中提出了自己最初的想法:业务应该采纳 TDD 在开发中的方式,为客户提供反馈:


(图片来自 Labnotes

软件开发主要的问题在于正确识别要解决的问题,从而避免“造成浪费的生产机器”。为此,我们需要一种新的方式来衡量事实,而不是意见(或自大),这样一来,我们就能更好地衡量我们的应用在真正工作时的使用状况了。

TDD 是为了设计并验证代码。EDD 以跟踪目标的方式来检查业务是否正常工作。

EDD 框架基于 A/B 测试,该测试起源于市场调研方法,会将基线受控样本与多种单个变量的测试样本进行对比,以判断哪两种选择会提升响应率。

Assaf Arkin 是 EDD 框架 Vanity 的作者,他这样描述 EDD

EDD 是基于事实的软件开发。CEO 们告诉自己的小姨子、小舅子们一些公司里的故事,由此而产生的意见和看法会成为一些软件的需求来源。EDD 与此类开发方式完全相反。EDD 从想法开始,为了衡量这些想法,EDD 会征集真实人群的反馈:你的客户、网站的访问者、使用自己开发的软件的人等等。EDD 以迭代的方式寻找证据。 TDD 和 BDD 提供的工具能够帮助我们改善代码质量,并保证我们的代码能够完成规格说明的要求,而 EDD 帮助我们找出要开发哪些特性,以及从何入手:它帮助我们发现将会成为规格说明的东西。

使用 Vanity 这个 Rails 插件,A/B 测试可以通过以下 5 个步骤完成:

  1. 定义一个 A/B 测试: ```

experiments/price_options.rb

ab_test “Price options” do
description “Mirror, mirror on the wall, who’s the better price of all?”
alternatives 19, 25, 29
metrics :signup
end

复制代码
2. 为用户展示不同的选择: ```
<h2>Get started for only $<%= ab_test :price_options %> a month!</h2>
  1. 使用 track! 方法衡量转换程度: ```

class SignupController < ApplicationController
def signup
@account = Account.new(params[:account])
if @account.save
track! :signup
redirect_to @acccount
else
render action: :offer
end
end
end

复制代码
4. 生成报告:
![](https://static001.infoq.cn/resource/image/77/17/77b05fb54c30a1cf7ba4613c4bef5517.png)
(图片选自 [Labnotes](http://labnotes.org/))
5. 观察收集的数据,衡量表单的效率:
![](https://static001.infoq.cn/resource/image/42/ab/4285d9b2dfac0b70ad65b6b7a7a061ab.png)
(图片选自 [Labnotes](http://labnotes.org/%C3%B7))
为了了解更多 EDD 相关的内容,InfoQ 与 Assaf Arkin 进行了交流:
**InfoQ:** 你是如何产生 EDD 这个想法的?是在为自己的新项目 [apartly](http://apartly.com/ "apartly") 尝试了 [A/Bingo](http://www.bingocardcreator.com/abingo "A/Bingo") 之后?还是通过 Nathaniel 的演讲?
> [Nathaniel](http://blog.talbott.ws/ "Nathaniel") 提出了 EDD,我就是咖啡喝多了。 在 RubyConf 几周前,Nathaniel 逗留在旧金山,我们一起吃了午饭。那时,我正在为 Apartly 设置一系列试验。我使用 A/Bingo 分割测试,Google Analytics 做某些度量,用其他东西做数据库查询。
>
> 设想一下,数据来自三个不同的地方,我得把它们弄到一起,生成报告。这可不容易,因为 Google Analytics 不知道 A/B 测试,而 A/B 测试也不知道 Google Analytics。每个试验中还存在代码测试路径的问题。这时你要如何测试你的试验和衡量指标呢?
>
> 喝过咖啡后,Nathaniel 把他要演讲的内容给我做了一个“电梯演讲”。听起来就像我当时正在做的,不过他已经提出了方法论,而我正在想办法东拼西凑。
>
> 然后他提到了重点部分。EDD 是一个概念框架,一种通过试验思考、构建、度量和精化代码的方式。如果已经有了一个实际的框架能够完成纯体力活,这样我们仅仅写少数几行代码就能编写试验,那该多好?我听到之后,脑子里马上就有声音在不停告诉我:“官人我要~~”
>
> 从那时起,这个声音就一直在我脑中回荡,到 [RubyConf](http://labnotes.org/2010/02/04/how-tdd-missed-the-point-introducing-edd/ "RubyConf") 之前,我用不长的时间开发完成了一个框架。它必须是功能最小化、但是切实可行的 EDD 框架,带有足够好的文档,并在生产环境中使用一段时间。除非我相信它能在生产环境中使用,否则我不奢望别人使用这些代码。
>
> 这就是 Vanity 产生的故事。
**InfoQ:** 目前主要是什么在驱动你的开发?测试?行为?试验?这个比率跟项目的成熟度有关么?
> 我把 EDD 和 TDD 放在一起用,而且无法想象只用一个是什么状况。 我们是一个小创业公司,有很多雄心壮志,很多想法。把这些想法转化成完美的产品和可行的市场,需要一段时间。我们早期的一些直觉可能是对的,一些可能需要调整,有些方法可能被证明不靠谱。这是创业公司的常态。成功的关键在于快速迭代,在钱花光之前发现完美的 [产品和市场组合](http://www.amazon.com/Four-Steps-Epiphany-Steven-Blank/dp/0976470705 " 产品和市场组合 ")。
>
> 那就得像忍者那样写代码。用最小的付出得到产出,这样就能测试当初的直觉正确与否,验证想法是否可行。
>
> 我们没有时间让代码过度工程化,以应对所有的“万一”情况。大多数情况下,6 个月的时间内,我们就会在发展方向上做出改变,因为市场告诉我们这么做,而且突然间我们就得丢掉不需要的功能了。那时,你就会对自己当初没有过度开发感到庆幸。
>
> 做到精益的另一方面在于去除多余的库存。我们不能承受垃圾代码和死亡特性的拖累。我们移除特性的速度和添加的速度一样快。
>
> 看清脚下的路,这让我们能够自由试验不同的想法,因为犯错的后果没多严重。只要你没有进行大批量的前期开发,或是承诺在特性上维护多年,你就能随意尝试不同的东西。如果一种试验没有成功,扔掉它,再试试别的吧。
>
> 要想这么做,代码必须易于改变,易于调试,而且足够可靠,才能做到持续部署。我们需要好的测试套件,以保证不出问题。现在我们的代码与测试之比为 1:3.4。我们有单元测试、功能测试和基础测试,它们在后台持续运行,这要感谢强大的持续集成服务器软件 Autotest,它帮我们发现开发机器上的 bug,还能在预发布服务器上运行,以应对部署方面的问题。
>
> 因此,这些防线防止我们把有问题的代码送出去。TDD 在控制代码质量上就扮演这样的角色,并允许我们试验新想法,快速做出产品变更。但是你如何判断改变什么呢?哪些想法值得探索?
>
> 我们都从直觉开始,但仅有直觉永远不够。从纽约时报上读到创业公司的故事,看起来总是创始人们有了一个好主意,然后马上就挖到了第一桶金。这些故事让人感觉很好。可实际上,创始人们有无数的主意,其中大部分都是垃圾,有一些还算可以,只有最好的才能被人记住。成功的创业公司会倾听市场,然后追随少数几个可以胜出的想法。
>
> 我们采取迭代的方式开发,但是我们的迭代不是为了完成下一个特性或是推进特性列表的开发。迭代是为了尝试,更多地了解客户,再使用这些知识判断下一个迭代要做什么。我们的进度度量使用 Eric Ries 所称的“[经验证的学问](http://www.startuplessonslearned.com/2009/04/validated-learning-about-customers.html " 经验证的学问 ")”。
>
> 你的客户最关心哪些特性?哪些变化能让他们更开心?哪些功能没人关注,你可以放心移除?如果同一件事情有两种方式可以完成,你会采取哪一种?
>
> EDD 可以回答这些问题。它把一个想法放到实际情况中,查看反应情况,以此测试这个想法在实践中的实际情况。EDD 和 TDD 是互补的,没有 TDD,我们无法完成准时(Just-in-time)开发、快速迭代和多种试验。没有 EDD,我们也许能开发出质量极高、刀枪不入的代码,可是没有人用。EDD 能帮我们找到一款杰出软件的秘密配方。
**InfoQ:** 你认为 EDD 可以用在任何类型的软件开发之中么?有没有想过它是否适用于过度工程化的 Java 工程项目,或是类似于你之前在 Intalio 开发的应用?它是否仅仅适用于高访问量的网站?
> 人们有个印象:A/B 测试讲的是渠道、转化率和登陆页面【译注 1】。市场研究的相关人员已经多年使用统计方法来分析和细分市场。他们把这些实践带到 Web 上,让我们无法逃避阅读 A/B 测试和登陆页面优化。 A/B 测试不仅仅是登录表单。实际上,大多数试验与登录表单或是市场活动没什么关系。
>
> 作为软件开发人员,我们的工作不仅仅是构建功能特性并确定它们能正常工作。重点在于构建有用的功能,人们会使用这些功能并从中受益。如果你是软件开发人员,你是否仅仅为了构建而构建,还是为了某个客户而构建呢?你是否愿意开发没有人会去用的代码?还是愿意开发很多人都觉得有用的代码?
>
> 我们种很多人都有兼职项目,因为这让我们对某款软件的某个部分负有完全的责任,而且对我们的每次决策要完全承担其后果。
>
> 我可以用一个问题总结我们在 Apartly 上的开发过程:“它能拨动指针吗?"
>
> 我们对好几个度量指标感兴趣,比如注册数(获得)、邀请数(推荐)、订阅数(收入)等等。这些都是指针。使用我们所能获得的有限资源而做的一切,都要在这些度量指标的某一个上取得成果。也许我们能得到更多的注册人数,也许是更多的回头访客,也许是 Twitter 上更多的击节赞叹。
>
> 不仅每个人都能看到这些指标,而且它们也已经被植入到开发过程之中。度量指标和试验是代码库的一部分,它们被签入到源代码控制系统种,并经历测试和预发布过程。
>
> 测试有限开发会让人先写一个失败的测试,然后开发必要的代码以通过测试。与之类似,我们会先从一个基线指标开始,然后编写代码让这个指标向期望的方向变化。(一般都是向上的,不过有些指标,比如每分钟的 WTF 个数【译注 2】,一定是要向下的。)
>
> 能否把这样的方法应用到大规模流量网站之外的应用?总是有一个度量指标能够说明问题的。当你用消息队列方式替换同步交互之后,能否改善响应时间?是否降低服务器在高负载下的故障发生几率?是否更易于部署新的服务?简而言之,是否有任何可度量的效应,或是以前浪费的工作量现在看起来更好了?
>
> 如果没有任何可度量的结果,那就会导致启动很多开发工作,因为解决问题听起来很有趣,而且继续存在,因为无法证明它所导致的效率低下,同时已经成本已经沉没下去了。只要引入度量指标,有趣工作的定义就变化了。突然之间,某些工作变得有趣,因为你能看到后果。
>
> Nathaniel 提出的 EDD 框架需求列表的第二点就是“各个层面都能访问得到”。不能只是面向客户。我们希望在软件栈的各个层面都能度量。而且每个组件都要负责,证明它的价值。
**InfoQ:** 很难衡量 TDD 和 BDD 的 ROI,而且结果也许无法马上显现出来(当然更不可能是实时的了)。这样一来,可能很难说服管理层和决策人员利用 TDD 和 BDD 的好处。有没有可能 EDD 因为可以提供直接和可量化的数据,而被管理人员青睐?
> 悲哀的是,我不认为 EDD 能够让你的猪头老板(Pig Head Boss)变得更聪明、更讲道理。 IT 部门,扩展到很多业务和企业软件公司,对于用户有一种偏执。当你不必听从用户的时候,有时就会树立起一种围绕着客户的文化,开支票的人或职位就是客户。客户总是对的,他们也不会容忍任何并非他们提出的变更,因此他们希望看到一个路线图,看到从 0 到 100% 的持续进度过程。这是典型的瀑布式方法。
>
> 在另一端,有这样的公司和项目,他们无法强迫人们使用自己的软件。他们必须讨好自己的用户,让用户高兴,让用户的生活在某方面变得更好。衡量成功的方式不是看在财年结束时完成了多少功能,而是赢得了多少用户。
>
> 当你以交付功能的方式度量成功时,绘制精美的甘特图就是你的指路明灯。还可能把甘特图放大,贴在办公室最大的那面墙上。如果以客户的满意度来度量成功会发生什么?让市场部门把自己的季度董事会报告在整个公司里面流传么?这在交付和反馈之间可是有三个月的延迟啊。
>
> 有些公司会在角色扮演练习中产生用户原型,并围绕着这个想象出来的用户原型设计软件。其他公司已经想办法实施充满寓意的“吃你自己的狗食”,有些公司只开发自己内部也会用到的软件。可如果你的市场不是软件开发人员怎么办?
>
> 如果你理解软件的运作方式,就能知道按代码行数衡量工作效率毫无意义。通过特性或故事点数衡量软件也好不到哪里去。二者都是在衡量和优化优先级次高的效果。工作效率没告诉你多少有用的东西。
>
> 反之,选取最重要的业务度量指标。Dave McClure 给它们起了个绰号:“[海盗的指标](http://www.slideshare.net/dmc500hats/startup-metrics-for-scottish-pirates-aarrr)”,包括获取率、激活率、保持率、推荐率和收入。雇佣最聪明的人,包括开发团队,找出如何提升获取率,提高保持率,增加收入。
>
> 目的不是为了获得业务上的量化回报。如果量化回报必须从市场部门逐渐转向开发经理,再下放到团队主管,那就会出现带宽和延迟方面的问题。关键是要把开发人员直接放到第一线去,把度量指标植入流程之中,度量关键的业务目标。
>
> 我将其称为“后敏捷”,因为它构建于敏捷的成功基础之上,但是用“可验证的学问和关键指标”替换“可工作的软件作为进度的基础度量方式”。EDD 之于“后敏捷”,就像 TDD 之于敏捷。
EDD 会在未来几年成为标准吗?它能否提供坚实有力的成效?还是仅仅是另外一个以 DD 结尾的缩略词?您怎么看?
** 查看英文原文:** [Experiment Driven Development - The Post-Agile Way](http://www.infoq.com/news/2010/02/edd-post-agile "Experiment Driven Development - The Post-Agile Way")
** 译注 **
1. 渠道(funnel)、转化率(conversion)和登陆页面(landing pages):这三个词都是在线网络营销的常用词汇。funnel 表示网站方希望访问者为达到某个目标而使用的页面路径。详细解释可参考 [Google Analytics 的解释](http://www.google.com/support/googleanalytics/bin/answer.py?hl=en&answer=55580)。网站转化率,是指将网站访问者转化为常驻用户的比率。登陆页面(landing page)是指网站访问者通过点击站外链接到达当前网站的页面,可能是主页,也可能是网站中其他页面;可参考 [Wikipedia 页面](http://en.wikipedia.org/wiki/Landing_page "Wikipedia 页面 ")。
2. WTF:粗口“What the fxxk”的简称,WTFs/m 的含义,可参考 [该页面](http://www.osnews.com/story/19266/WTFs_m)。Bob 大叔在自己的 [《Clean Code》](http://www.douban.com/subject/3032825/) 一书中对此也有引用。
2010 年 3 月 07 日 22:361646
用户头像

发布了 479 篇内容, 共 131.6 次阅读, 收获喜欢 36 次。

关注

评论

发布
暂无评论
发现更多内容

食堂就餐卡系统设计

Arvin

架构设计

食堂就餐卡系统架构设计

武鹏

微服务架构中分布式事务实现方案怎样何取舍【转发】

古月木易

微服务

架构师训练营-第一周-学习总结

Anrika

极客大学架构师训练营 架构总结

区块链如何打通征信行业的“任督二脉”?

CECBC区块链专委会

CECBC 区块链技术 征信 数据共享

食堂打卡系统架构设计文档

Frank Zeng

ARTS Week 1

黑色柳丁

ARTS 打卡计划

产品经理越来越不值钱了吗?

Neco.W

产品 产品经理

架构师训练营-第一周学习总结

zcj

极客大学架构师训练营

二叉树视频|留美六年毅然归国,85 后技术 VP 金超:我想把工业智能做好

二叉树视频

写作平台 二叉树 年少有为

第一周学习总结:

武鹏

作为一个架构师,我是不是应该有很多职责?

架构师修行之路

程序员 架构 架构师

架构师训练营-开营

zcj

极客大学架构师训练营

TOGAF认证自学宝典

涛哥

架构 企业架构

架构师训练营第1周——学习总结

在野

极客大学架构师训练营

微服务架构中分布式事务实现方案怎样何取舍

奈学教育

数据结构与算法之基础入门

shirley

数据结构 算法

极客架构师训练营第一周

大丁💸💵💴💶🚀🐟

原创 | TDD工具集:JUnit、AssertJ和Mockito (二十)编写测试-参数化测试

编程道与术

Java 学习 编程 TDD 单元测试

系统梳理主流定时器算法实现的差异以及应用

奈学教育

定时器

架构师训练营第一周课堂学习总结

Frank Zeng

架构师训练营-架构方法:架构师如何做架构

Pontus

极客大学架构师训练营

中台迷局丨只做IT的中台是个神棍

人称T客

SaaS:小企业向左、大企业向右

人称T客

架构方法论学习总结

架构师训练营第一周总结

hifly

软件架构 架构师 极客大学架构师训练营 #总结#

系统梳理主流定时器算法实现的差异以及应用

古月木易

定时器

【架构师训练营】第一个周课程总结

Mr.hou

极客大学架构师训练营

c# 之linq——小白入门级

moonlucy

架构师训练营 - 食堂就餐卡系统设计

Pontus

极客大学架构师训练营

架构师训练营-第一周作业

zcj

极客大学架构师训练营

试验驱动开发——“后敏捷”之道-InfoQ