Cucumber 之 Step Definitions


最近一直处于厌食、失眠、出虚汗的状态,体力明显不支。下午跟小伙伴做完例行的健身操,头晕眼花、恶心耳鸣。仔细想想,饮食、休息、健身和工作学习本该是个良性循环,必须环环相扣。一环欠了债,整个系统都有可能崩塌。所以“身体是革命的本钱”,这句话一点儿不假。工作学习固然重要,但和吃饭睡觉一样,是个长期的过程,不能一蹴而就,也不能三天打鱼两天晒网。


我们已经学习了Cucumber的Gherkin语法。“.feature”文件就是用Gherkin语法结合自然语言编写的Scenario和Step,用来告诉Cucumber“要做什么”。那么,具体“怎么做”又是如何实现的呢?

先来回顾一下创建一个Cucumber Test的三步走战略:

Step 1. 创建features folder;

Step 2. 编写.feature文件;

Step 3. 编写step definitions.


没错,“怎么做” 就是由Step Definition来实现。

Step Definitions:

Step Definition相当于业务领域和程序领域之间桥梁,用ruby语言编写。它都有什么作用呢?可以从两个方面来理解:

a. 解释:将“.feature”文件中的Scenario和Step解释成可执行的ruby代码;

b. 决定做什么:告诉系统按照ruby自动化代码块来执行。


Step vs Step Definition:

我们必须搞清楚两个概念:Step和Step Definition

(1). Step

“.feature”文件包含多个Scenario,Scenario又包含多个Step(由Gherkin关键字引导,自然语言编写)。就step本身而言,它只是一种文件,需要Step Definition赋予它生命。

(2). Step Definition

Step Definition是一段ruby代码,存放在features/step_definitions文件目录里。它仿佛在告诉Cucumber:“如果你看到一些长得像***的step,就是我要让你做***”。因此Cucumber需要将Step Definition与“.feature”文件中的Step进行match。

用一个例子来解释这个match。

Feature: Cash withdrawal
  Scenario: Successful withdrawal from an account in credit
    Given I have $100 in my account 
    When I request $20
    Then $20 should be dispensed

Cucumber执行feature时,从Scenario的第一步“Given I have $100 in my Account ”开始扫描,同时查找是否存在任何Step Definition来匹配这段自然语言。

下面是与之匹配的Step Definition:

Given /I have \$100 in my Account/ do
# TODO: code that puts $100 into User's Account goes here
end

Step Definition就是用正则表达式来做match。这段代码就是在告诉Cucumber:“如果你看到一些长得像‘/I have \$100 in my Account/’的step,就是我要让你做‘TODO"’部分的内容”。

在ruby里,正则表达式由“/”符号开始,由“/”符号结束。这里的dollar符用“/”标记,以此来使dollar符保持其字面意思。因为在ruby里,dollar符具有特殊意义。

Step Definition 之 方法(Methods):

Step Definition是一段ruby代码,因此它必须包含方法,变量,参数,返回值等等。

那么它的方法是什么呢?

我们在Step Definition里看到的Given、When和Then就是Cucumber方法。

在上述例子中,调用Cucumber的Given方法,告诉Cucumber要注册一个Step Definition。通过Given方法传递两个概念:

(1).用以匹配“.feature”文件中step的正则表达式“/I have \$100 in my Account/”和一段ruby程序块。

(2).Cucumber保存这段ruby程序块,直到找到与之匹配的step后来执行这段程序。

实际上,在Step Definition与Step进行匹配时,Cucumber并不关心是Given、When还是Then方法。因为在底层,所有的keywords只有同一个别名:Cucumber:: RbDsl#register_rb_step_definition。那这些keyword在Step Definition里究竟有什么意义呢?其实真的没什么意义,只为了帮助我们理解程序。而step与step definition的match只看正则表达式。

Step Definition 之 参数(Arguments):

说完了方法,再来说说参数。

细心地人就会发现,正则表达式“/I have \$100 in my Account/”表示“我有100 dollar”,但如果我还有其它金额呢?难道需要重新写一个step definition吗?当然不是。这时候,step definition的参数(arguments)就需要出场了,Cucumber可以将具体值以参数的形式传递给程序块。

我们可以用通配符”.*”来代替正则表达式中的具体数值,并增加参数(Arguments)。Step Definition通过正则表达式匹配到Step以后,将从step中获取的具体数值传递给Step Definition中的参数。

Given /I have \$(.*) in my Account/ do |amount|
# TODO: code that puts $100 into User's Account goes here
end

当然,也可以限定参数的范围,比如数字。

Given /I have \$([0-9]*) in my Account/ do |amount|
# TODO: code that puts $100 into User's Account goes here
end

比如小写字母:

Given /I have \$([a-z]*) in my Account/ do |amount|
# TODO: code that puts $100 into User's Account goes here
end

当然,还有很多简写字符,比如:

\d 代表数字[0-9].
\w 代表字母、数字、下划线[A-Za-z0-9_].
\s 代表空格,Tab或者回车[ \t\r\n]. 

和大多数程序语言一样,Cucumber也支持多个参数。

Step Definition 之 返回结果:

前面讲到,“.feature”文件告诉Cucumber要做什么,Step Definition告诉Cucumber怎么来做。那它如何来通知Cucumber是成功了还是失败了呢?

和大多数测试工具一样,Cucumber也通过抛异常(Exception)来传递失败。Cucumber执行Scenario时,一次执行一个Step,如果这个Step执行通过,它就继续移去执行下一个Step;如果失败,就抛出一个异常。下图展示了Cucumebr如何来执行Scenario。


与其他测试工具不同的是,Cucumber的返回结果略为复杂。包含四种状态:

  • Undefined

  • Pending

  • Failed

  • Passed

Undefined:

正如上面的流程图所示,当Cucumber找不到与Step Definition对应的Step时,将Step标记为Undefined状态,并结束Scenario的执行。其余的Step要么被标记为Skipped,要么同时被标记为Undefined状态。

Undefined状态通常为黄色标记。

Skipped用蓝色标记。

Pending:

当Step Definition发现Step Definition未完成时,就会将Step标记为Pending状态,并结束Scenario的执行。同样,其余的Step要么被标记为Skipped,要么被标记为Undefined状态。

Cucumber怎么知道Step Definition未完成呢?这需要Step Definition亲自告诉它。


像这样,当你的ruby程序块未完成时,可以手动将其标记Pending。这样Cucumber就会知道Step执行失败了,但是是因为一种特殊的原因。

Pending 状态通常也为黄色标记。

为什么也要用黄色呢?我个人认为,Undefined表示未找到Step Definition,Pending状态表示Step Definition找到了,但未完成,从某种意义上来讲,这两种状态的性质是一样的。

Failed:

当Step Definition执行失败时,就抛出一个失败的异常,将step标记为Failed,并结束Scenario的执行。同样,其余的Step被标记为Skipped。

Failed状态用红色标记。

Passed:

当step执行通过时,Cummber将该step标记为Passed,转而执行下一个Step。

Passed状态用绿色标记。

更多Cucumber知识,请回顾:

  • 初识Cucumber

  • 第一个Cucumber Test

  • Cucumber语法之Gherkin

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的Cucumber示例,帮助你了解Cucumber的基本用法。 1. 首先,需要安装Cucumber,可以通过以下命令在命令行中安装: ``` gem install cucumber ``` 2. 在项目中创建一个features目录,用于存放测试用例,然后在该目录下创建一个名为example.feature的文件,用于编写测试用例。 ``` Feature: Example feature As a user I want to see a welcome message So that I know the application is working Scenario: User visits homepage Given I am on the homepage Then I should see "Welcome to the application" ``` 该测试用例描述了一个场景,即用户访问网站首页时应该看到欢迎信息。 3. 接下来,需要编写step definitions,用于将测试用例中的文本转换为可执行的代码。在项目中创建一个名为step_definitions的目录,然后在该目录下创建一个名为example_steps.rb的文件,用于编写step definitions。 ``` Given(/^I am on the homepage$/) do visit '/' end Then(/^I should see "(.*?)"$/) do |text| expect(page).to have_content(text) end ``` 该文件中定义了两个step definitions,分别对应测试用例中的Given和Then。 4. 最后,可以在命令行中运行测试用例,使用以下命令: ``` cucumber features/example.feature ``` 运行结果应该如下所示: ``` Feature: Example feature As a user I want to see a welcome message So that I know the application is working Scenario: User visits homepage # features/example.feature:6 Given I am on the homepage # features/step_definitions/example_steps.rb:1 Then I should see "Welcome to the application" # features/step_definitions/example_steps.rb:5 1 scenario (1 passed) 2 steps (2 passed) ``` 这表明测试用例已经通过了。 以上是一个简单的Cucumber示例,希望能够帮助你了解Cucumber的基本用法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值