BDD 从踢弟弟到逼弟弟

恩里科 · 2016年12月20日 · 最后由 applepen 回复于 2019年10月31日 · 3313 次阅读
本帖已被设为精华帖!

从踢弟弟到逼弟弟

自从 2015 年 10 月十八届五中全会决定全面放开二胎,一对夫妇可以生育两个孩子。身边不少头胎生了女孩的夫妻积极响应国家号召,生下了第二胎,而且大部分人二胎生的都是男孩,凑得个好字,儿女双全。

但是,有人的地方就有江湖,有江湖的地方就有竞争。许多头胎的孩子,本来颠颠高高兴兴,万千宠爱在一身。突然一天,爸爸妈妈告诉他们,要当哥哥/姐姐了,懵懂的他们还不知道是什么回事。直到弟弟/妹妹降生,全家人注意力迅速转移,哥哥/姐姐们才知道歌里唱的 “由来只有新人笑,有谁听到旧人哭” 是什么意思。小小年纪开始了体会怨憎会、求不得之苦。

若是二胎是弟弟,自己是女儿身,而又生在那重男轻女之家,那苦真叫作苦过弟弟。老大心理上如不能适应,则有可能对弟弟下手,各种踢弟弟。然而小孩动手不知轻重,踢弟弟容易有伤痕,被大人发现了那可是胆汁送黄莲,苦上加苦。于是,扭曲的小孩另寻方法,改为心理上摧残弟弟,从踢弟弟转为逼弟弟。

国外就有一些小孩,早早就从踢弟弟转为逼弟弟。他们就是

敏捷开发工程师

他们搞了个敏捷宣言

  • Individuals and interactions over processes and tools
  • Working software over comprehensive documentation
  • Customer collaboration over contract negotiation
  • Responding to change over following a plan
  • That is, while there is value in the items on
  • the right, we value the items on the left more.

简单来说是加强沟通,忙尽快出能工作的软件。

目的是为了摆脱过去那种大型项目开发的中因为因循繁琐的流程、维护大量的文档所造成的低效率,从而适应项目小型化,拥抱需求变化,营造一个欢乐开发的海洋。

为了实现其中的第二点,尽快提供工作的软件 (Working software),有些小孩又搞了一个敏捷实践,叫做

踢弟弟 (TDD Test-Driven Development)

他搞了几个原则

  • write a "single" unit test describing an aspect of the program
  • run the test, which should fail because the program lacks that feature
  • write "just enough" code, the simplest possible, to make the test pass
  • "refactor" the code until it conforms to the simplicity criteria
  • repeat, "accumulating" unit tests over time

概括来说,是先写一小段某个功能的测试代码,测试失败,再写实现代码,测试成功,再迭代下一个功能。

这对于单元测试与开发是很有用的一种实践。因为踢弟弟是要求在写代码之前就要想好怎么测,测什么,这解决了可测性低的问题。另外,踢弟弟还可以提高代码的测试覆盖率,令 bug 在编码阶段就能被发现。减少上线后发现问题,修复问题的指数级增长成本。

然而,踢弟弟也有它的不足。

  • 它解决的是代码级的验证,但是测试代码与需求的符合问题解决得不是很好,非技术人员、客户看不懂代码,无法评审测试是否符合需求。
  • 测试代码可能写得太大或者太小,令开发人员效率下降。这与测试代码与功能对应不起来有很大关系。

于是,又有一些小孩扩展了踢弟弟,提出了

逼弟弟 (BDD Behaviour-Driven Development)

他们发现,如果将自然语言按照一些简单语法组织起来,代码将会非常容易解释与处理。使用这种方法可以让非技术人员、客户可以参与到需求的确认与验收当中。

我们看一下两个例子

Scenario: Refunded items should be returned to stock
  Given a customer bought a black sweater from me
    and I have three black sweaters left in stock.
   When he returns the sweater for a refund
   then I should have four black sweaters in stock.


场景: 微信聊天
假如  手机安装了微信
当  用户打开微信
那么  手机会出现用户的微信聊天界面

以上就是逼弟弟使用的叫做 Gherkin 的语言,它的理念是使用自然语言来描述功能,而且强调的是使用例子来说明需求功能。是不是跟敏捷开发中的用户故事 (User Story) 很像?嗯,因为它们都是一个妈生的。

其实只要我们回顾一下敏捷宣言,就会发现,逼弟弟干的事就是解决个体之间互动与客户协作这两个问题。

逼弟弟的需求研讨会 (Specification Workshops)

那么,我们使用这种语言,把需求一个个用例子列出来,客户/产品、开发、测试三方一起讨论与确认。

逼弟弟的由外而内的开发模式 (Outside-In Development)

然后,开发人员使用 BDD 工具 (JBehave, Cucumber, Behave) 去运行、实现测试脚本。再一点点编写实现功能代码,走到所有的功能都运行通过。
由于开发的过程是从最接近用户的 UI 界面开始,再想到内部设计,因此它称为由外而内的开发模式。如果再加上由内而外的过程,嗯,《开发人员的自我修养》就等着你来写了,你叫史坦尼斯拉夫斯基对吧?

回到 Gherkin 语言,我们上面提到它需要遵循一定的简单语法

  • Scenario(场景),说明功能的例子
  • Given(假如),构造测试的环境条件
  • When(当),给予的输入,可以是用户,也可以是外部系统,也可以是系统本身定时/条件触发的
  • Then(那么),系统的输出,或者说行为

若干个 Given,When,Then 构成一个 Scenario,若干个 Scenario 构成一个 Feature,若干个 Feature 最终构成一个系统的完整功能需求。

逼弟弟的不足

由于自然语言的天生缺陷,光用文字总会有一些歧义会产生。例如

冬天能穿多少就穿多少
夏天能穿多少就穿多少

Gherkin 语言不能完全解决自然语言的歧义问题,如果有图片,那会很有帮助。然而,现有的 Gherkin 语言与 BDD 工具并不支持插入图片。

碰壁

那你问我资不资瓷,我当然资瓷啊。你们啊,要努力提高姿势水平。国外那 Stack Overflow,水平不知道比你们高到哪里去,我跟他们谈笑风生。

支持的办法就是将 Gherkin 语言与 Markdown 语法 crossover,用 Markdown 标签来插入图片。
就像这样

场景: 微信聊天
假如  手机安装了微信
当  用户打开微信
那么  手机会出现用户的微信聊天界面
![微信聊天界面](wechat.jpg)

但是由于 Markdown 不支持图片尺寸定义,图片不能缩放,效果可能就会变成
markdown image

图片会显得很大,一页都显示不完,体验很差。

有人提出使用 ![微信聊天界面](wechat.jpg =320x) 这种办法,可惜的是,不是所有工具/网站都支持。

又有人提出另外写一个 css 文件来解决这个问题,但是 Stack Overflow 上很多人表示,另外维护一个文件很不友好。而且,在逼弟弟这个事情上,让非技术人员去写 css 更加不切实际。因此,我暂时推荐的解决办法是在 Markdown 中使用 HTML 标签

就像这样

场景: 在搜索框搜索目的地
    假如      用户在手机上登录了手机助手
    当     用户在手机助手上选择导航
    那么      手机助手进入导航页面
#<img src="./Main.jpg" width="240">

效果就会是这样

markdown with html img

这里有个 tricky 的地方,就是 html 标签前面要用井号注释起来,这样写的好的 markdown 文件,只要将后缀名从.md 改为.feature,就可以使用各种 BDD 工具运行解释,不影响运行啦。

天才

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 20 条回复 时间 点赞

有点意思

描述生动又不夸张,蛮好

那你问我资不资瓷,我当然资瓷啊。你们啊,要努力提高姿势水平。国外那 Stack Overflow,水平不知道比你们高到哪里去,我跟他们谈笑风生。 😁 这句亮了,我江信江疑...

方法不错,增强了 feature 文件的描述性。

但加了图片感觉维护工作量更大了,而且也还是没办法很好地说清楚大部分需求(例如针对 UI 的,点击 xx 按钮后不同状态应该有怎样不同的界面效果)。感觉目前 bdd 比较适合描述逻辑类的需求,这类需求比较适合通过纯文字描述。

目前接触的产品都比较喜欢用原型工具展示需求,界面与逻辑结合,表达的内容也是大家都相对能看得懂。BDD 的描述能力相比之下局限性还是比较大。

你们现在有在落地 BDD 吗?效果如何?

好萌。。。

BDD 就是坑啊,已经试过了,坚持了不太久

思寒_seveniruby 将本帖设为了精华贴 12月22日 20:24

加精理由: 讲解的很生动. 对 BDD 持保留态度. 欢迎长期交流.

记得留打赏二维码

10楼 已删除

#4 楼 @chenhengjie123 正在推,解决了 story 写得比较模糊的问题。也在探索更好的实践。有人说这份 feature 由测试来写,产品或客户来确认。

#11 楼 @kelequy 我们之前强推过一次,用于做无界面的服务端接口测试。feature 由业务测试写,代码由测试开发写。当时遇到的几个主要问题是 story 的风格不统一(不同人写的风格不一样,会增大后续测试开发编写代码的沟通成本和维护成本)、粘合代码编写成本较高(如果不用确保和 feature 对应,写起来能更快更爽)、维护比较麻烦(一旦有更改,feature 和代码都要调整,偶尔也会出现 feature 不用改,但代码要调整的情况)。

总的来说,当时活文档这个特性的带来的好处没太大感觉(测试报告中更直观地看出具体是哪个步骤出错?),但由于这个特性带来的编写速度慢、维护困难的问题倒是深有体会。

#12 楼 @chenhengjie123 story 风格不一致这个问题我也遇到,所以说要先定好一个 feature 编写的规范,界面、页面、动作、查找关键词、分隔符这些都要约定好,不然写粘合代码会吐血。公共的粘合代码也要做封装,减少重复劳动。是挺多东西要先想好,才会有好的效果。

解决客户、非技术人员、开发和测试的需求沟通问题,有一个技术叫 Fit 表格 有人玩过吗?

fir.im CI Weekly #9 | 揭秘阿里 Docker 化实践之路 中提及了此贴 12月29日 11:16

#14 楼 @atom992 玩过 Fitnesse,不过太冷门了。显然 BDD 是和客户沟通的更好的 replacement.

@026 @chenhengjie123
以前用 Cucumber ,希望的效果是:新员工 2 小时内看完能了解业务轮廓和核心价值,这里新员工包括产品、运营、客服、开发、测试、客户等任何会接触这个产品的人。演示的时候先用这样的 feature :

场景: 超级管理员登录        
  假如 "admin"是超级管理员
  那么 "admin"能看见后台管理界面

演示完第一句话是:“不要写这样的 feature 。” 要写这样的:

场景: 有新公司接入"卖得快"
  假如 "小明"是"卖得快"的运营
  当 "小明"创建公司"瓦雷亚"
  当 "小明"创建"瓦雷亚"公司的管理员"小红"
  当 "小红"给"瓦雷亚"公司配置会计科目表
  当 "小红"创建仓库
  当 "小红"创建产品"投石机"
  当 "小红"创建零售商"小刚"
  那么 "小刚"能从"瓦雷亚"公司购买"投石机"
  假如 "小霞"不是"瓦雷亚"公司的零售商
  那么 "小霞"不能从"瓦雷亚"公司购买"投石机"

控件、点击、输入、页面……这些词都不能用,不能出现账户名、密码、选择器。

一些参考:
《实例化需求》
《Cucumber:行为驱动开发指南》
YOU’RE CUKING IT WRONG

fir.im CI Weekly #10 | 2017 DevOps 趋势预测 中提及了此贴 01月05日 11:58

逼弟弟入门可能好一点,但是越用越觉得不够用,不够用咋办?转踢弟弟咯。。。

长期如何呢?如果业务越做越复杂,测试代码逻辑也要越来越复杂,请问够用吗?特别希望有 BDD 实际项目落地经验的朋友谈谈。

感觉只能用于轻量级的项目。如果遇到场景复杂逻辑纵横交错的大型项目,感觉 bdd 吃不消

感觉挺好的,BDD 的 feature 的文件书写规范是一个问题,感觉可以跟自动化测试联系起来,让人在写 UI 自动化测试用例跟业务都联系在一起,更加清晰(遇到有些人的测试代码逻辑不清晰,让人看不懂)。至于 Aglie 还是有点难

找个做一次现实的分享,一定更精彩

BDD 目的是达成从产品业务 - 开发 - 测试对于需求的共识。我是不是可以认为,有了 BDD。自动化测试团队就可以不用额外去写自动化测试用例了(是指 Excel 文档)?

需要 登录 後方可回應,如果你還沒有帳號按這裡 注册