您的位置:首页 > 其它

一个简单的Cucumber+Capybara的BDD开发例子

2012-11-13 10:24 501 查看
Cucumber是一个用来做BDD( Behavior Driven Design)的工具。你可以用自己的语言来写场景(scenarios)和定义(definitions).

Capybara可以用来模拟用户对浏览器(browser)的访问。

下载和配置

下载cucumber到本地:  

$gem install cucumber


创建好你的rails项目以后, 编辑 Gemfile 加上Cucumber:

group :development, :test do
gem "rspec-rails", ">= 2.0.1"
gem 'cucumber-rails'
gem 'database_cleaner'
end

创建你的测试

在你的Rails项目里, Cucumber测试在 features文件夹下面的 .feature后缀文件里。 可参考Cucumber目录结构和执行过程

你可以创建一个 contact.feature 文件写上一些场景(scenario):

Feature: Contact me
In order to get in touch
A visitor
Should send me a message by contact form

Scenario: Sends a contact message
Given I am on the contact page
And I fill in "contact visitor name" with "John"
And I fill in "contact visitor email" with "john@mail.me"
And I fill in "contact subject" with "Hello"
And I fill in "contact message" with "Great post!"
When I press "Send message"
Then page should have notice message "Your message was successfully delivered."


* 注意缩进  ( 注: 是否应该是缩进2格?  上面代码是缩进4格的)

场景(scenario)是由很多步骤(steps)组成的。

一个步骤(step)是一个验证(validation)或者一个更简单的测试(simple test).

开始运行cucumber命令:    

$ bundle exec cucumber

将得到警告说步骤没有定义:

cucumber_test$ bundle exec cucumber
Using the default profile...
Feature: Contact me

(....)

You can implement step definitions for undefined steps with these snippets:

Given /^I am on the contact page$/ do
pending # express the regexp above with the code you wish you had
end

Given /^I fill in "(.*?)" with "(.*?)"$/ do |arg1, arg2|
pending # express the regexp above with the code you wish you had
end

When /^I press "(.*?)"$/ do |arg1|
pending # express the regexp above with the code you wish you had
end

Then /^page should have notice message "(.*?)"$/ do |arg1|
pending # express the regexp above with the code you wish you had
end


这里要用capybara模拟浏览器的访问。

在 features/step_definitions/  文件夹创建 navigation_steps.rb

require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))

Given /^I am on (.+)$/ do |page_name|
visit path_to(page_name)
end

When /^I go to (.+)$/ do |page_name|
visit path_to(page_name)
end

When /^I press "([^\"]*)"$/ do |button|
click_button(button)
end

When /^I click "([^\"]*)"$/ do |link|
click_link(link)
end

When /^I fill in "([^\"]*)" with "([^\"]*)"$/ do |field, value|
fill_in(field.gsub(' ', '_'), :with => value)
end

When /^I fill in "([^\"]*)" for "([^\"]*)"$/ do |value, field|
fill_in(field.gsub(' ', '_'), :with => value)
end

When /^I fill in the following:$/ do |fields|
fields.rows_hash.each do |name, value|
When %{I fill in "#{name}" with "#{value}"}
end
end

When /^I select "([^\"]*)" from "([^\"]*)"$/ do |value, field|
select(value, :from => field)
end

When /^I check "([^\"]*)"$/ do |field|
check(field)
end

When /^I uncheck "([^\"]*)"$/ do |field|
uncheck(field)
end

When /^I choose "([^\"]*)"$/ do |field|
choose(field)
end

Then /^I should see "([^\"]*)"$/ do |text|
page.should have_content(text)
end

Then /^I should see \/([^\/]*)\/$/ do |regexp|
regexp = Regexp.new(regexp)
page.should have_content(regexp)
end

Then /^I should not see "([^\"]*)"$/ do |text|
page.should_not have_content(text)
end

Then /^I should not see \/([^\/]*)\/$/ do |regexp|
regexp = Regexp.new(regexp)
page.should_not have_content(regexp)
end

Then /^the "([^\"]*)" field should contain "([^\"]*)"$/ do |field, value|
find_field(field).value.should =~ /#{value}/
end

Then /^the "([^\"]*)" field should not contain "([^\"]*)"$/ do |field, value|
find_field(field).value.should_not =~ /#{value}/
end

Then /^the "([^\"]*)" checkbox should be checked$/ do |label|
find_field(label).should be_checked
end

Then /^the "([^\"]*)" checkbox should not be checked$/ do |label|
find_field(label).should_not be_checked
end

Then /^I should be on (.+)$/ do |page_name|
current_path.should == path_to(page_name)
end

Then /^page should have (.+) message "([^\"]*)"$/ do |type, text|
page.has_css?("p.#{type}", :text => text, :visible => true)
end


在 features/support/ 文件夹 增加一个 support文件  paths.rb

module NavigationHelpers
def path_to(page_name)
case page_name

when /the home\s?page/
'/'
else
begin
page_name =~ /the (.*) page/
path_components = $1.split(/\s+/)
self.send(path_components.push('path').join('_').to_sym)
rescue Object => e
raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
"Now, go and add a mapping in #{__FILE__}"
end
end
end
end

World(NavigationHelpers)


再次跑一边测试:

$ bundle exec cucumber


现在,你可以做代码方面的事了。  写 models,  controllers, views, routes.

这儿是我的例子, 步骤定义的是简单的浏览(navigation), 但你可以写更复杂的测试, 要让场景简单,比如 When I fill contact form可以定义成这样:

When /^I fill contact form$/ do
visit contact_form_path
fill_in('contact_visitor_name', :with => "John")
fill_in('contact_visitor_email', :with => "john@mail.me")
fill_in('contact_subject', :with => "Hello")
fill_in('contact_message', :with => "Great post! Bye.")
click_button("Send message")
end


原文: http://loudcoding.com/posts/quick-tutorial-starting-with-cucumber-and-capybara-bdd-on-rails-project/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐