I code it

Code and Life

Cucumber简介

cucumber是一个ruby下的BDD工具,开发ruby on rails的时候,一般会采用rspec作为BDD的工具,但是cucumber可以使得BDD的过程更为“有趣”一些。cucumber采用文本格式来描述feature, 然后设置不同的场景,并验证在这些场景下,软件可以预期的工作。单元测试更多关注的是代码级别,各种情况下,对象可以做出预期的响应,主要由开发人员完成;而cucumber测试,则更多的是业务级别,非开发人员/业务专家可以理解测试。

cucumber主要由两部分组成:feature文件及step文件。feature使用cucumber定义的一种DSL描述,非常易读,写的比较好的feature文件甚至可以做到和README文件一样。而step则负责解释feature中的一些模式,并控制流程,执行逻辑等。

这篇文章介绍一个简单的示例:作为一个普通用户,想要使用搜索引擎来搜索一些公司/组织的名称,希望得到一个页面,页面中应该包含公司/组织的站点链接URL。搜索引擎可能是google或者其他。

那么,可以开始编写feature文件,feature的格式与yml有些类似,基于缩进的方式来布局,通常包含feature节和scenario节。我们先来编写feature节:

   1: Feature: search on google
   2:     In order to find out the url of some company or organization
   3:     As an regular computer user
   4:     I want to search it from web

feature节通常使用这样的格式进行描述:

   1: Feature: what test is this feature all about
   2:     As a [role]
   3:     I want to [do something]
   4:     So that [I can get some value about that feature]

 

即作为某个角色,我想要做一些事情,这样我可以得到一些对业务有价值的结果。而scenario则描述一个场景,如:

   1: Scenario: search thoughtworks on google 
   2:     Given I am on the page of 'https://www.google.com/ncr'
   3:     When I search for 'thoughtworks'
   4:     Then I should get 'www.thoughtworks.com' at the result page

scenario的格式通常如下:

   1: Scenario: description of scenario
   2:     Given [pre-condition]
   3:     When [do a action]
   4:     Then [get result of action]

即假设我在某种场景下,做了一个动作,那么会得到一个预期的结果。可以看到,feature文件在可读性上非常友好,对于测试人员/业务专家都非常有用。

接下来,我们可以来看看step文件,step文件是一个ruby脚本,其中包含对feature中场景的匹配及当匹配是要做的动作。这种工作方式非常强大,在很多软件中都被采用,如vim/sed等。

   1: require "rspec"
   2:  
   3: Given /^I am on the page of '([^']*)'$/ do |engine|
   4:     visit engine
   5: end
   6:  
   7: When /^I search for '([^']*)'$/ do |keyword|
   8:     fill_in 'gbqfq', :with => keyword
   9:     click_on 'gbqfb'
  10: end
  11:  
  12: Then /^I should get '([^']*)' at the result page$/ do |link|
  13:     page.should have_selector('a', :href => link)
  14: end

首先visis/fill_in/click_on等方法都是在capybara中定义的,visit用于访问一个url;fill_in接受两个参数,页面上的css选择器以及一个字符串,它用以在页面上找到选择器选中的元素,然后将第二个参数中的字符串填入;click_on则作用与link或者button上,完成页面元素的点击。

Given/When/Then均接受一个正则表达式及一个可选的ruby块(block是ruby中非常好用的功能,与python中的lambda或者javascript中匿名函数类似)。当匹配到正则表达式时,执行这个块,在块中可以引用到匹配到结果作为参数。

cucumber则可以将feature和step结合起来,从而完成自动测试的流程,完成feature和step之后,可以通过cucumber命令来运行该测试:

pass

当然,cucumber可以导出HTML版本的报告:

cucumber-features-cuke

一个推荐的cucumber布局为:

cucumber-structure

step文件定义在step_definitions目录中,通用的ruby模块定义在support目录中,所有feature则定义在features目录中。

比如,这个小示例的support中有一个env.rb,其中定义了一些全局性的配置信息:

   1: require 'rspec'
   2: require 'rspec/expectations'
   3:  
   4: require 'capybara/cucumber'
   5: require 'capybara/session'
   6: require 'json/pure'
   7:  
   8: BASE_URL = "http://www.google.com.hk"
   9:  
  10: Capybara.default_driver = :selenium
  11: Capybara.run_server = false
  12: Capybara.default_selector = :css
  13: Capybara.default_wait_time = 30
  14: Capybara.ignore_hidden_elements = false
  15: Capybara.app = BASE_URL
  16:  
  17:  
  18: FileUtils.mkdir_p 'build/reports'

 

这个示例主要讨论cucumber在测试外部的(非ruby应用)时的简单实用,主要是与capybara结合起来,测试web应用的例子,更多的信息可以参考其站点

Comments