`

今天你BDD了吗?

    博客分类:
  • BDD
BDD 
阅读更多

    转载:http://www.iteye.com/topic/417899

Feature: Sign in 
  In order to get access to protected sections of the site 
  A user 
  Should be able to sign in 

    Scenario: User is not signed up 
      Given no user exists with an email of "email@person.com" 
      When I go to the sign in page 
      And I sign in as "email@person.com/password" 
      Then I should see "Bad email or password" 
      And I should not be signed in      

    Scenario: User is not confirmed 
      Given I signed up with "email@person.com/password" 
      When I go to the sign in page 
      And I sign in as "email@person.com/password" 
      Then I should see "Your account is not active" 
      And I should not be signed in 

   Scenario: User enters wrong password 
      Given I am signed up and confirmed as "email@person.com/password" 
      When I go to the sign in page 
      And I sign in as "email@person.com/wrongpassword" 
      Then I should see "Bad email or password" 
      And I should not be signed in 

   Scenario: User signs in successfully 
      Given I am signed up and confirmed as "email@person.com/password" 
      When I go to the sign in page 
      And I sign in as "email@person.com/password" 
      Then I should see "Signed in successfully" 
      And I should be signed in 

   Scenario: User signs in and checks "remember me" 
      Given I am signed up and confirmed as "email@person.com/password" 
      When I go to the sign in page 
      And I sign in with "remember me" as "email@person.com/password" 
      Then I should see "Signed in successfully" 
      And I should be signed in    
      When I return next time 
      Then I should be signed in 



第一印象就是一段关于用户登录的文档描述吧? 
但实际上,这是一段实际项目中关于用户登录场景的集成测试“代码” 

测试即文档? 
准确来说,以上代码是在一个ROR项目中使用Cucumber进行BDD开发的一个场景描述(测试)。 

什么是BDD? 
http://en.wikipedia.org/wiki/Behavior_Driven_Development 
这不是文本重点,有兴趣的同学可以自行搜索更多文章。 

为什么要BDD? 
说到BDD,就不得不提TDD(http://en.wikipedia.org/wiki/Test-driven_development) 
TDD的开发流程: 
 

Javaeye上有篇老帖子: 什么是“测试驱动开发” (http://www.iteye.com/topic/20063 ),点出了为什么要进行TDD的几个关键问题: 
第一,自然语言的描述容易产生歧义 
第二,不能自动化地验证 
第三,不能保证文档与程序同步 

TDD强调的是功能模块的测试,很多人都愿意使用单元测试,想尝试TDD,但都会有个问题,不知从哪里开始下手,而我们面向更多的是对一个场景的实现,因此BDD应运而生,更符合开发者的思维习惯。 

做开发,不能没有文档。我们做开发时,一般都是先接到一个需求描述(简单文档),我们作为开发者,要做的工作就是实现这个功能(场景)的代码编写,例如用户注册、用户登录、忘记密码的流程。 
而Cucumber就是为我们提供了这么一个工具,让我们能在用简单语言描述我们要做的事情同时,也顺带完成了测试代码的编写,剩下的就类似是做填空题一样,逐步编写实现代码,让所有测试都通过。当所有实现代码都出来了,一个完整的项目也就出来了(文档+代码+测试)。这也符合Rails DRY原则,不要做重复工作。 


引用
“软件工程课讲得清楚,只有源代码的软件不能算软件,因为它不可理解、不可维护;源代码加上文档,才算是程序员完整地交付了自己的工作。”


引用自 http://www.iteye.com/topic/20063 

我觉得还需要加上测试,才算是一个完整的项目。 

怎么在Ruby on Rails 中怎么使用Cucumber进行BDD开发? 
什么是Cucumber? 
项目主页:http://cukes.info/ 

引用
Cucumber is Aslak Hellesøy’s rewrite of RSpec’s “Story runner”, which was originally written by Dan North. (Which again was a rewrite of his first implementation - “RBehave”). Early versions of “Story runner” required that stories be written in Ruby. Shortly after, David Chelimsky added plain text support with contributions from half a dozen other people. 


为什么选择Cucumber? 
在 Rails 已经有一些BDD 工具: Rspec (http://rspec.info/) 
使用的测试代码类似: 

Ruby代码  收藏代码
  1. describe MovieList do   
  2.   context "when first created" do   
  3.      it "should be empty" do   
  4.        movie_list = MovieList.new   
  5.        movie_list.should be_empty   
  6.      end   
  7.   end   
  8. end  



虽然也很DSL,但还不够简明、直观,“代码”的味道还是很重。对比之下,反观Cucumber的测试“代码”,即使是团队中不会编程的角色也能看得明白在描述什么。如果团队足够NB,可以有一个负责程序设计 的leader专门负责把需求用Cucumber的features来描述,根据各人的能力和工作量,再分发给其下的负责编码的开发人员进行实现的编码。 

Cucumber的开发过程 
 
(from http://www.pragprog.com/titles/achbd/the-rspec-book) 

具体过程,7个步骤: 

引用

1: Describe behaviour in plain text 
2: Write a step definition in Ruby  
3: Run and watch it fail  
4: Write code to make the step pass  
5: Run again and see the step pass  
6: Repeat 2-5 until green like a cuke 
7: Repeat 1-6 until the money runs out  



简单来说就是:写用例->跑测试->看结果->写实现->换个用例,再来一次 

具体安装设置细节略过,Cucumber新手上路可以看视频: 
http://railscasts.com/episodes/155-beginning-with-cucumber 
或者文字版: 
http://asciicasts.com/episodes/155-beginning-with-cucumber 

Cucumber能做什么? 
看看用Cucumber可以描述、测试多复杂的场景: 
测试发邮件?没问题: 
 

甚至可以把一个用户进行填写注册表单、登录自己的邮箱、查收激活邮件、点击激活链接的整个故事流程都跑起来: 
 

又一个常见场景: 
已注册用户忘记密码,然后通过点击“忘记密码”链接,系统发送激活链接到用户邮箱,用户通过打开邮箱中的更改密码链接,进入新密码修改页面,修改新密码后能成功登录: 
 

用cucumber features -n 命令跑测试的效果: 
 

一些基本技巧: 
在其他场景中,经常会用前面测试过的“一个注册并激活的用户”,每次都copy一次? 
Don't repeat yourself! 
此时就可以在Cucumnber的steps中把上述过程都封装成一句话: 

Ruby代码  收藏代码
  1. Given I am a confirmed user and signed in as "tom@iamtom.com" with password "mypassowrd"  



实际的封装steps代码是: 
 

第一步是新建一个已激活的用户,第二步是用这个用户来进行登录操作,这样就得到了一个“注册并已激活,已经成功登录的用户” 

看看另一个测试用例,也是比较“经典”的在一个项目中新建一个todo item的场景: 
 

其中 

Ruby代码  收藏代码
  1. Then the project which name is "A trip" should has a todo which name is "To meet David"  


的steps实现为: 
 

通过这样的封装,可以用来断定任意两个model数据对象是否关联 
可通用的描述语句为: 

Ruby代码  收藏代码
  1. Then the {modelA} which {attr} is "{A}" should has a {modelB} which {attr} is "{B}"  



一些进阶技巧: 
http://railscasts.com/episodes/159-more-on-cucumber 
示范如何做通过设置模板句法来解决一些重复、相似的features编写技巧 

如: 

Ruby代码  收藏代码
  1. Feature: Manage Users  
  2.         In order manage user details  
  3.         As a security enthusiast  
  4.         I want to edit user profiles only when authorized  
  5.   
  6.   Scenario Outline: Show or hide edit profile link  
  7.     Given the following user records  
  8.       | username | password | admin |  
  9.       | bob      | secret   | false |  
  10.       | admin    | secret   | true  |  
  11.     Given I am logged in as "<login>" with password "secret"  
  12.     When I visit profile for "<profile>"  
  13.     Then I should <action>  
  14.   
  15.   Examples:   
  16.     | login | profile | action                           |  
  17.     | admin | bob     | see "Edit Profile"     |  
  18.     | bob   | bob     | see "Edit Profile"     |  
  19.     |       | bob     | not see "Edit Profile" |  
  20.     | bob   | admin   | not see "Edit Profile" |  
  21.   
  22. 4 scenarios  
  23. 16 passed steps  



但我个人不推荐过多的使用这种技巧,我认为Cucumber的features就应该保持简明易懂,去除代码的味道。features里套用了模板,人阅读时就需要用脑“即时编译”,进行循环、替换,这就又会给缺乏编程经验的人作为功能描述文档阅读时造成障碍,削弱了“测试即文档”的作用。DRY不是圣旨,适当的重复并不是罪恶。 
另外,在cucumber中使用webrat进行测试时,还可以搭配使用Selenium 来测试JS,十分强大,这会是我们下一步的尝试。 
感受: 
当我第一次看到Cucumber的测试代码,第一个感觉就是这真的是“代码”吗?很奇幻的感觉。 
现在感觉Cucumber中的features的本质无非是一些用关键词堆砌的文本段落,然后一个用正则替换的方法来匹配替换真正的测试语句, 很简单的手段,但最重要的背后的思考,它是bdd所强调一种开发风格、思维方式。 
在用Cucumber开发了一段时间后,完全没有感觉不适或强迫感,每次看到测试通过后的一片绿色,心情就很轻松愉快。能很明确每一步在做什么,而且做完修改后,都能知道修改有没副作用。Ruby之父说用ruby开发是happy coding,开始以为just joking,现在真的有这种感觉,现在用Cucumber进行BDD则是多了一个项:happy testting 
疑问? 
I18n怎么处理? 

Rails 有了Cucumber后,还需要单元测试吗? 
http://www.pathf.com/blogs/2009/06/cucumber-rocks-but-its-not-a-replacement-for-unit-tests/ 

关于这个问题,我和同事都认为是需要的,只是在一些细节上有争议。 

我在实际进行项目开发时,都是针对一个应用场景、案例、用户故事的思路来进行代码编写的,只有当流程跑通了(features 的测试通过),下一步才是保证这个流程在一些异常情况下也能得到预期的结果(用单元测试来保证,如更多的边界测试),简单来说是就 setup features->coding->unit test 

同事认为,应该在写完cucumber的测试代码后,再写单元测试代码,最后再写实现代码,简单来说是 setup features ->unit test->coding 

我不清楚到底那种才是正确的BDD流程,这需要继续探讨。 

以上是我一个月来尝试BDD的经验分享,作为抛砖,其中或许有片面或错误的见解,望有同学们不吝指教、一起探讨。 

有研究表明,三个星期可以改变或养成一个习惯,那你今天开始BDD了吗? 

相关链接: 
What is Test-driven Development?
http://edn.embarcadero.com/article/29690 

Behavior Driven Development Using Ruby 
http://www.oreillynet.com/pub/a/ruby/2007/08/09/behavior-driven-development-using-ruby-part-1.html 
http://www.oreillynet.com/pub/a/ruby/2007/08/30/behavior-driven-development-using-ruby-part-2.html 

Introduction to BDD with Cucumber 
http://www.engineyard.com/blog/2009/cucumber-introduction/ 

A NEW LOOK AT TEST-DRIVEN DEVELOPMENT 
http://blog.daveastels.com/files/BDD_Intro.pdf 


本文PDF版(带排版): 
http://www.iteye.com/topics/download/69f11949-58ed-33dd-8307-884d280ebad5

分享到:
评论

相关推荐

    BDD算法实现 - BuDDy开源代码

    BuDDy是一个开源库,专门用于实现BDD算法,尽管它已有一段时间没有更新,但它的设计思想和实现策略对于理解和学习BDD算法仍然极具价值。 **BDD的基本概念** BDD是一种有向无环图,其中每个节点代表一个布尔变量或者...

    二叉决策图BDD原理、应用与实现介绍

    二叉决策图(Binary Decision Diagram, 简称BDD)是一种用于表示布尔函数的图形数据结构,它在计算机科学,特别是在硬件验证、软件模型检查和优化等领域有着广泛的应用。BDD通过一种紧凑的方式存储布尔表达式,可以...

    BDD100K-实例分割数据集

    BDD100K-实例分割数据集 数据集介绍 背景: 现有的驾驶数据集在视觉内容和支持的任务方面不足,无法研究自动驾驶的多任务学习。研究人员通常被限制在一个数据集上研究一小组问题,而现实世界的计算机视觉应用程序...

    python BDD 框架入门

    本教程将带你了解如何入门Python的BDD框架,特别是`Behave`。 **1. Behave简介** `Behave`是Python的一个BDD框架,它允许开发者使用类似Gherkin语法编写可读性高的测试用例。Gherkin是一种领域特定语言(DSL),它...

    驾驶视频数据集 BDD100K

    《驾驶视频数据集 BDD100K:自动驾驶与图像识别技术的重要里程碑》 BDD100K,全称为Berkeley DeepDrive 100K,是一个极具影响力的驾驶视频数据集,它由10万个高质量的行车视频组成,旨在推动图像识别技术在自动驾驶...

    BDD100K数据集,包含所有的训练集和测试集,以及darknet文件,可以直接训练

    Darknet文件的引入,意味着你可以直接利用这个数据集和YOLO框架进行目标检测模型的训练。YOLO以其高效的检测速度和相对较高的精度,在自动驾驶、监控等领域有着广泛应用。 **挑战与价值** BDD100K数据集的复杂性和...

    Quick Start for BDD 2007

    【Business Desktop Deployment (BDD) 2007 快速入门】 Microsoft Solution Accelerator for Business Desktop Deployment (BDD) 2007 是微软推出的一款解决方案加速器,旨在帮助企业更高效、便捷地部署Windows ...

    提取bdd100k中的labels中的json格式数据到txt格式

    提取bdd100k中的labels中的json格式数据到txt格式,数据包括traffic light的颜色以及在图中的box的位置

    bdd100k数据集标签转COO再转YOLO程序

    本文将详细介绍如何将"BDD100k"数据集的标签转换为YOLO格式,以便于使用YOLO模型进行训练,如yolov7或yolov5。 "BDD100k"(Berkeley DeepDrive 100K)是一个大规模的多模态语义理解和自动驾驶数据集,包含10万张带...

    BDD资料包文件

    **行为驱动开发(Behavior Driven Development,BDD)** 是一种软件开发方法,它强调以用户的行为为中心,通过对话和实例化场景来定义系统需求。BDD 的目标是提高沟通效率,确保开发团队和非技术人员(如产品经理或...

    使用Cucumber+Rspec玩转BDD全集.rar

    在他们下载的chm始终打不开或有问题。 ... 使用Cucumber+Rspec玩转BDD(1)——用户注册 使用Cucumber+Rspec玩转BDD(2)——邮件激活 ...使用Cucumber+Rspec玩转BDD(3)——用户...使用Cucumber+Rspec玩转BDD(7)——测试重构

    BDD入门指南

    BDD入门指南主要面向在大数据领域中工作的业务分析师、数据科学家和数据工程师。BDD,即行为驱动开发(Behavior-Driven Development),是一种敏捷软件开发的技术,它鼓励软件项目中的跨职能团队成员之间的协作。BDD...

    行为驱动开发(BDD)全面介绍-时牧敏捷 antlr-complete

    **行为驱动开发(BDD)全面介绍** 行为驱动开发(Behavior-Driven Development,简称BDD)是一种敏捷软件开发方法,它强调从用户的角度出发,通过明确的业务行为来定义系统需求,进而指导软件开发过程。BDD的核心...

    bdd100ktoxml-master.zip

    标题"BDD100ktoxml-master.zip"和描述中的信息暗示了这是一个与计算机视觉和数据转换相关的项目,特别是涉及到BDD100K数据集的处理。BDD100K(Berkeley DeepDrive 100K)是一个大规模的、多样化的自动驾驶图像数据集...

    yolov5训练bdd100k自动驾驶数据集模型文件

    在本话题中,我们将深入探讨基于Yolov5框架训练的自动驾驶数据集——BDD100K,以及如何利用这些模型文件进行高效的目标检测。Yolov5是一种流行的实时目标检测算法,广泛应用于自动驾驶、视频监控等领域。下面将详细...

    YOLOv7在BDD100K数据集多种天气场景实验

    1. 使用YOLOv7在BDD100K数据集上的实验,包含可直接运行的代码,代码文件功能说明,代码运行说明; 2. 包含非常充分地实验结果,精确度曲线,召回率曲线,AP曲线,P-R曲线,IoU,MAP等; 3. 同时提供许多实验图片和...

Global site tag (gtag.js) - Google Analytics