初尝Cucumber

使用cucumber 实作了个小小的例子,来感受一下小黄瓜的魅力:P。

正文

做了一个用于计算的专案,名为calculator。

calculator会做这样的事情:

如果你输入了:
2+2
那么它会输出4
如果你输入了:
3*3
那么它会输出9
……

其实就是一个简单的计算器。

好,我们开始吧。

终端运行:

rails new calculator
cd calculator

建立专案calculator, 安装cucumber。参考:Cucumber-Rails

在gemfile文件中添加 cucumber-rails:

database_cleaner这个gem是用来清理测试数据的,可加可不加,不过建议添加。

终端运行:

bundle install
rails g cucumber:install

会自动生成一些文件:

它帮我们生成好了features文件夹, 还有step_definitions.

让我们删除rails自带的test:

rm -rf test

终端输入cucumber试试:

显示Deprecated了,针对这个问题我 Google了一下,你可以在cucumber-rails的issues346中看到, 但是没有找到解答,如果你留意,你会发现config文件下的cucumber.yml里面确实有~@wip, 如果你尝试着把所有的~@wip 替换成not @tag 会出现报错,鉴于它并不影响测试,所以你可以选择无视这些Deprecated:P

好,我们继续添加测试文件吧!新增adding.feature文件:

touch features/adding.feature

adding.feature文件的内容如下:

终端运行cucumber,显示如下:

会发现报错了,我们并没有定义step_definitions来告诉cucumber如何将这些直白的英文转换成专案中具体的action。但是,你也会发现小黄瓜贴心的地方,它告诉你step definitions里面要加一些snippets。

新建features/step_definitions/calculator_steps.rb 文件,文件内容如下:

【其实就是复制了它告诉我们的代码:P】

再次运行cucumber试试:

显示一个pending,2个skipped了,我们来修改一下calculator_steps.rb,让第一个step可以pass。

Given("the input {string}") do |string|
  @input = string
end

When("the calculator is run") do
  pending # Write code here that turns the phrase above into concrete actions
end

Then("the output should be {string}") do |string|
  pending # Write code here that turns the phrase above into concrete actions
end

运行cucumber,step1 pass.

第二个step pending,Oops,我们继续。

这里可以梳理一下,第一步是input,最后是output,所以第二步应当是调用了method进行计算。好,我们添加一个ruby文件: calc.rb, 修改calculator_steps.rb,如下:

Given("the input {string}") do |string|
  @input = string
end

When("the calculator is run") do
  @output = `ruby calc.rb #{@input}`
end

Then("the output should be {string}") do |string|
  pending # Write code here that turns the phrase above into concrete actions
end

运行cucumber,step2 pass.

注意到这里calc.rb还只是一个空文件,而且需要注意calc.rb是在根目录下。

继续修改calculator_steps.rb, 让第三个step pass:

Given("the input {string}") do |string|
  @input = string
end

When("the calculator is run") do
  @output = `ruby calc.rb #{@input}`
end

Then("the output should be {string}") do |string|
  expect(@output).to eq string
end

calc.rb中加入一行,使得output等于预期:

print eval (ARGV[0])

不了解eval的用法?👉戳这里Dynamic evaluation

简单来说,这里input是”2 + 2”,那么eval(input)就是会4.

这时继续运行cucumber,出现这样的报错:

显示except是undefined method,那是由于没有安装RSpec,在gemfile中加入

gem 'rspec-rails'

然后bundle install,再次运行cucumber,Pass!

整个流程算是走完了。

以上就是一个cucumber测试的基本流程了。

cucumber的整个语法结构有个名字叫做Gherkin,例子中我们的add.feature就是遵守着Gherkin的语法。

Gherkin的大致结构类似这样:

The End

实作的时候还是踩了些坑的,看报错却又找不到哪里出问题,看stack overflow也是一脸懵逼,这里略去一万字的吐糟……

推荐:

the cucumber book‘s forums

Cucumber:行为驱动开发指南