BDD 从踢弟弟到逼弟弟

恩里科 · December 20, 2016 · Last by applepen replied at October 31, 2019 · 4666 hits
本帖已被设为精华帖!

从踢弟弟到逼弟弟

自从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 将本帖设为了精华贴 22 Dec 20:24

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

记得留打赏二维码

10Floor has been deleted

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

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

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

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

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

fir.im CI Weekly #9 | 揭秘阿里 Docker 化实践之路 中提及了此贴 29 Dec 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 趋势预测 中提及了此贴 05 Jan 11:58

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

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

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

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

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

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

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up