在Cucumber Feature文件中如何使用变量?

9
我的团队正在使用Cucumber测试REST API。步骤会调用API,而场景有类似于“给定我使用JSON YYY调用XXX”这样的内容。
在功能文件中,设置JSON变量并在不同场景中使用/操作它们是否是一种非常糟糕的做法?我们的许多测试都使用相同的JSON对象,只修改1-3个元素。我想在某些场景中尝试以下操作:
“给定我将JSON YYY中的J元素更新为K值,并将其保存为<NewJsonVariable> ...”
这似乎是一个糟糕的做法,因为Cucumber本身就是一种有争议的REST API测试工具。然而,我有一些功能要测试,其中包含5-10k行代码(分成多个文件),但我估计可以将其缩减到500-1k行,并使其更易读。唯一的问题是测试编写者/读者现在必须记住JSON变量,但测试足够短,一次只有2或3个变量。

请问您使用Cucumber多长时间了,您的项目是用哪种语言实现的?顺便说一句,询问意见并不是SO正在寻找的问题类型。您可以考虑重新措辞,以便有人能够提供客观答案而不是主观答案。 - James B. Byrne
@JamesB.Byrne 我已经使用Cucumber大约3个月了。我们的核心代码是Java,但我们使用Ruby测试所有REST服务的Cucumber。由于我们没有官方的QA团队,所有开发人员都在编写Cucumber测试,我希望能让这一过程更加轻松。 - user1097108
你可能希望阅读一些关于BDD和Cucumber的文档,特别是这个链接:https://github.com/cucumber/cucumber/wiki/Cucumber-Backgrounder,这是我对该主题的看法。基本上,借用一个短语来说,你“cuking it wrong”:http://www.elabs.se/blog/15-you-re-cuking-it-wrong。 - James B. Byrne
为了让自己更轻松,您需要放下当前的方法,考虑一下Cucumber应该为您的项目带来什么价值。生成1000行的特性文件是一个相当好的线索,表明您的团队没有抓住重点。 - James B. Byrne
1
很有趣的是,当你询问如何做一些不可能的事情时,人们会开始质疑你的动机;说你不理解这个工具。 - max pleaner
@maxple 没错!看起来这既是可能的,也是有用的 https://dev59.com/i3rZa4cB1Zd3GeqPzS5E#20553312 (我计划使用它创建临时电子邮件以测试发送,变量本身可以留在功能之外。) - Andy Hayden
2个回答

5
Cucumber的目的在于允许用简单的英语表达每个场景中应该发生的内容。HOW是在步骤文件中详细阐述的。你在特性语句中放入了过多的细节。这将是一个维护噩梦,所以可能不会维护。通过可预测的结果,场景应该大致如下:
Scenario The first thing our REST service does
  Given I have a REST service  
  When I connect with request "something" 
  Then I should get this result  

在步骤文件中,您可以使用匹配器进行设置:
Given(/I have a REST service/i) do
   j_element = 'first value'
   . . .
end

请求在匹配器中进行了指定:
When(/I connect with request "(.*)"/i) do |something|
  # Set new value
  j_element = something
  #send jason call 
  . . .
  return @result_set = visit( rest_api_path( j_element ) )
end

结果会在匹配器中进行检查:

Then(/I should get this result/i) do
   check_result( result_set )
   . . .
end

在方法之间随意传递实例变量并不被认为是良好的方式,因此您应该在步骤文件中定义访问器方法以优雅地处理这个问题。

def result_set()
  @result_set ||= 'nothing set yet'
end

将在多个位置使用的测试放在自己的方法中,并将要检查的内容作为参数传递。

def check_result( result )
  assert . . .
  #or
  result.j_element.should . . .
 end

所有你目前放在功能文件中的详细内容应该放在匹配器后面的 do-end 块中,或者放在帮助方法(如 check_resultresult_set)中。这样可以使读者更清楚地理解你的场景应该完成什么任务,并且这也有助于简化你的步骤。


3
黄瓜是用于进行BDD而不是测试工具,特别不适用于进行详尽测试的工具。对于你正在进行的测试类型,最好使用像RSpec这样的单元测试工具。因为单元测试/规范是用编程语言编写的,所以添加变量、循环等以进行多个测试非常容易。
编写功能/场景的原因是为了描述行为,即你正在做什么,可能更重要的是,为什么要这样做。你的场景并没有做到这一点,相反它们详细记录了如何使用你的API。如果要使用黄瓜开发你的API,你应该以更抽象的方式编写场景。
Scenario: I can create a book
  Given I am an author
  When I create a book
  Then I have a book

请注意,此场景没有关于书籍如何创建的详细信息,没有提到json,甚至没有提及api。
简而言之,将您现有的场景转移到单元测试工具中,并在那里引入变量和循环。您不能/不应该在特性文件中“编程”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接