gpt4 book ai didi

ruby - cucumber ruby -模块内的步骤

转载 作者:太空宇宙 更新时间:2023-11-03 16:58:58 24 4
gpt4 key购买 nike

背景
我正在编写一个黄瓜库,它有多种不同的步骤,可以跨多个项目使用,并试图将步骤定义的复杂性分解为3个不同的模块,用于iOS、Android和Web特定的项目,其中包括所有3个模块。
其中一个步骤库将包含大量基于安全性的步骤,我希望在使用这些步骤之前将这些步骤显式地包含到项目中。
根据配置中指定的内容,将显式包含项目拆分库:

if $profile[:app_type] == 'android'
World(ProjectSteps::Android)
else
if $profile[:app_type] == 'ios'
World(ProjectSteps::IOS)
else
World(ProjectSteps::Web)
end
end

这些不是为了取代helper方法,而是为了节省我们在启动新项目时的时间,还将允许我们以不同的方式编写特定于项目的步骤定义,这取决于我们是在测试web、本机iOS应用程序还是为具有完全相同功能而构建的本机Android应用程序但是不同到需要不同的步骤定义
问题
在定义了模块内的步骤之后,功能文件仍然可以愉快地执行此操作,即使该模块还没有包括在这样的“World”中: World(CommonSteps::Security),这是通常用来让cumber知道隐藏在模块内的helper方法的方法。
When 'I provide my personal details' do
select :title, 'Mr'
fill :first_name, 'John'
fill :last_name, 'Doe'

unless $profile[:app_type] == 'web'
click :progress
end

if $profile[:app_type] == 'android'
fill :postcode, 'TE37ER'
select :address, '1 Test Street'
click :progress
fill :occupation, 'Tester'
fill :company, 'Test Company'
click :progress
else
fill :occupation, 'Tester'
fill :company, 'Test Company'
unless $profile[:app_type] == 'web'
click :progress
end
fill :postcode, 'TE37ER'
select :address, '1 Test Street'
click :progress
end
end

此步骤定义试图同时测试3个应用程序,但它正在测试完全相同的功能、完全相同的场景和完全相同的功能。如果将其分为3步定义,那么在将来进行调试会更简单,但是可以为每个定义使用相同的功能文件(这不是不可能的,因为有许多应用在web和本机移动变体上共享完全相同的功能)在我看来,这种类型的步骤定义试图实现太多。
这将更容易维护,尽管更多,因为它更简单:
module ProjectSteps::IOS
When 'I provide my personal details' do
select :title, $user[:title]
fill :first_name, $user[:first_name]
fill :last_name, $user[:last_name]
click :progress
fill :occupation, $user[:occupation]
fill :company, $user[:company]
click :progress
fill :postcode, $user[:postcode]
select :address, $user[:line1]
click :progress
end
end
module ProjectSteps::Android
When 'I provide my personal details' do
select :title, $user[:title]
fill :first_name, $user[:first_name]
fill :last_name, $user[:last_name]
click :progress
fill :postcode, $user[:postcode]
select :address, $user[:line1]
click :progress
fill :occupation, $user[:occupation]
fill :company, $user[:company]
click :progress
end
end
module ProjectSteps::Web
When 'I provide my personal details' do
select :title, $user[:title]
fill :first_name, $user[:first_name]
fill :last_name, $user[:last_name]
fill :occupation, $user[:occupation]
fill :company, $user[:company]
fill :postcode, $user[:postcode]
select :address, $user[:line1]
click :progress
end
end
When 'some thing that is the same across platforms' do
# Some stuff
end

请记住,这是我试图实现的一个简单版本,并没有显示我试图解决的一些问题的全部复杂性。在这种情况下,我很可能使用 if/ unless版本,而不是拆分版本,但是有一些情况要复杂得多,可以分成3个部分。
我们还可以添加对在开发过程中发现的错误的无提示检查,以确保这些错误不会退化,并且由于web、android和ios应用程序具有不同的错误,我们最终会得到大量的 if/ unless语句。
我试过什么-我听到你问
我不是很亲近,就是很遥远。
GivenWhenThen在不同模块中无法正常工作,这就是为什么我必须搜索我认为它们是别名的方法。
下面是生成的代码:
require_relative 'xss.rb'
require 'cucumber'

module CommonSteps
module Security
Cucumber::RbSupport::RbDsl.register_rb_step_definition(
'I attempt to write a step definition that has to be included to work',
Proc.new {
# Some stuff here
})
end
end

注册步骤定义完全正确。但这是问题的一部分。我只想注册这个步骤定义,如果模块已经包含在我正在工作的项目中。
这也意味着,如果需要的话,我们可以切换iOS和Android的Web步骤,同时保持特性文件完全相同(是的,我知道 if语句是一件事,但是太多了,step-def变得非常复杂。)
编辑
我要实现的不是我们过去看到的“网络步骤”没有通用步骤显示代码,并且只使用我们与开发团队一起工作的业务部门达成一致的语言由于我们工作的许多项目都是跨平台的,所以我本质上是在尝试实现一些可以切换正在使用的步骤定义类型的东西-如果您使用Chrome,请使用此步骤定义的Web版本;如果您使用iOS,请使用此步骤定义的iOS版本;此外,还可以使用一种方法来包含由文本驱动的各种通用步骤,这些步骤可以链接回我们的页面对象模型—使场景完全基于业务。
Given I am on the "Personal Details" page # (generic)
When I provide my personal details # (non-generic, but Web, iOS and Android versions exist)
But leave the "First Name" field blank # (generic)
And I attempt to continue to the next page # (generic)
Then I should see a validation error for the "First Name" text box stating: "Please provide your first name" # (generic)

例如,如果验证是业务部门想要知道的工作,并且它是与业务部门达成一致的需求的一部分,那么是否有一种更易于业务理解的方式来传达这些信息-其中的原因是,我们希望确保用户填写信息,以便验证不显示,但如果他们不提供该信息,我们还应该测试在需要验证的场景中出现的验证。
我们使用页面对象模型的方式是“personal details”将在url映射中找到 :personal_details键。该键可以向下传递到下一步,链接到包含 Pages.personal_details键的 :first_name方法。我们所有的项目都使用这个设置,它是我们的核心助手方法库附带的文档的一部分。
我所要达到的目标不一定是按照我所建议的方式使用的坏习惯,但如果使用不当,可能会被当作坏习惯来使用。

最佳答案

在黄瓜的历史上,有好几次像这样的事情都是由黄瓜自己来做的,黄瓜本身就有网络步骤,这些步骤在一段时间前就被删除了它们现在在宝石https://github.com/cucumber/cucumber-rails-training-wheels中你可以从那里得到一些图书馆的建议。
也就是说,我强烈建议不要编写步骤定义库相反,我会编写一个方法库,可以由步骤定义使用。一个粗略的例子可能有助于说明这一点。
假设您有一个非常复杂的登录到应用程序的方法您可以编写一个真正复杂的步骤定义,处理各种登录事务,如

When I login (hugely complex regex to deal with things like ...
# loads of code to deal with you params and regex's and make things work with lots of different scenarios

或者你可以写一个方法
def login(as:, args={})
让人们在写东西的时候使用这种方法。

When 'I login' do
login as: @i
end

When 'I login as Fred' do
login as: create_or_find_user(firstname: 'Fred')
end


When 'I login as Fred with Jill's password' do
login as: @fred, password: @jill.password
end

helper方法提供实用程序,帮助您编写适合您的单个上下文的简单步骤定义。共享步骤定义限制您使用高度复杂且不能有任何特定于上下文的内容。
场景应该是特定于上下文的,并且允许灵活的简单语言,特定于它们所属的单个世界的上下文。他们应该只知道为什么要做什么,做什么,而不知道怎么做。根据定义,它们不共享,因此根据定义,它们也不执行步骤定义。
一旦你通过调用留下了一个步骤定义,你就进入了代码的领域,并且代码在共享方面非常有效
Cucumber学到了一个教训,即共享步骤定义是一个非常糟糕的主意(请参见 http://aslakhellesoy.com/post/11055981222/the-training-wheels-came-off)谨防重蹈覆辙。

关于ruby - cucumber ruby -模块内的步骤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44831487/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com