在黄瓜功能文件中使用变量?

use*_*108 5 ruby bdd automation json cucumber

我的团队正在使用Cucumber测试REST API。这些步骤将调用API,而方案具有诸如“鉴于我使用JSON YYY调用XXX”之类的内容。

在功能文件的背景中设置JSON变量,然后针对不同的场景进行操作/使用,这是非常不好的做法吗?我们的许多测试都使用只有1-3个已编辑元素的相同JSON对象。我想针对一个场景做这样的事情:

Given I update J element to K value in JSON YYY As <NewJsonVariable> ...

由于Cucumber本身是用于REST API测试的有争议的工具,因此这似乎是一种不好的做法,但是现在我想将变量放入该功能的组合中。但是,我有一些功能是5-10k行(分成多个文件),我估计我可以将其减少到500-1k行,并使它更具可读性。唯一的问题是,测试作者/阅读器现在必须将JSON变量保留在他们的脑海中,但是测试足够短,以至于一次只能有2或3个变量。

Jam*_*rne 5

The point of Cucumber is to allow plain English expression of WHAT is supposed to happen in each scenario inside the feature file. HOW that comes about is elaborated in the step files. You are putting far too much detail into your feature statements. This is going to be a nightmare to maintain so it likely will not be. With predicable results.

A scenario should probably go something like this:

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  
Run Code Online (Sandbox Code Playgroud)

In the step files you do the set up with the matcher:

Given(/I have a REST service/i) do
   j_element = 'first value'
   . . .
end
Run Code Online (Sandbox Code Playgroud)

The request is specified in the matcher:

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
Run Code Online (Sandbox Code Playgroud)

And the results are checked the in the matcher:

Then(/I should get this result/i) do
   check_result( result_set )
   . . .
end
Run Code Online (Sandbox Code Playgroud)

Since passing instance variables around willy-nilly directly between methods is not considered good form you should define accessor methods in your step files to handle this in an elegant fashion.

def result_set()
  @result_set ||= 'nothing set yet'
end
Run Code Online (Sandbox Code Playgroud)

Put tests that are used in multiple places inside their own methods and pass in what you want to check as an argument.

def check_result( result )
  assert . . .
  #or
  result.j_element.should . . .
 end
Run Code Online (Sandbox Code Playgroud)

您当前放入功能文件的所有详细内容都应放置在do-end匹配器后面的块内或辅助方法(如check_resultresult_set)中。这使得读者更清楚地了解您的场景应该完成什么,这也将帮助您简化步骤。


dia*_*ist 3

Cucumber 是一个用于执行 BDD 的工具,而不是一个测试工具,特别是不是一个用于进行详尽测试的工具。对于您正在进行的测试类型,使用 RSpec 这样的单元测试工具会更好。因为单元测试/规范是用编程语言编写的,所以添加变量、循环等来进行大量测试很容易。

编写功能/场景的原因是描述行为,即您正在做什么,也许更重要的是,您为什么这样做。您的场景实际上并没有这样做,而是详细记录了您如何使用 api。要使用 Cucumber 开发你的 api,你应该以更抽象的方式编写场景,例如

Scenario: I can create a book
  Given I am an author
  When I create a book
  Then I have a book
Run Code Online (Sandbox Code Playgroud)

请注意,此场景没有任何有关如何创建书籍的详细信息,没有提及 json,甚至没有提及 api。

TL/DR 将您现有的场景转移到单元测试工具并在那里引入您的变量和循环。您不能/不应该在功能文件中“编程”。