我有一个工作黄瓜设置。我的features/
文件夹包含功能和步骤定义,我可以在命令行调用cucumber
来运行测试套件。
我还有一个单独的脚本,我想启用它来调用一些黄瓜测试。我知道在黄瓜步骤定义中,可以从另一个步骤调用一步。但我不知道如何:
从relishApp cucumber api docs开始,我收集了这个:
require 'cucumber'
# run all features
runtime = Cucumber::Runtime.new
Cucumber::Cli::Main.new([]).execute!(runtime)
这将以与从命令行运行cucumber
完全相同的方式运行我的所有黄瓜测试,包括格式。但是,我不确定如何使用这种方法:
execute!
退出程序)。我也一直在寻找黄瓜源代码来尝试动态编写/调用步骤:
require 'cucumber'
Given(/foo/) {}
# this raises an error:
# NoMethodError: undefined method `register_rb_step_definition'
# for Cucumber::RbSupport::RbLanguage:Class
# from /usr/local/lib/ruby/gems/2.0.0/gems/cucumber/2.4.0/lib
# /cucumber/rb_support/rb_dsl.rb:28
# :in `register_rb_step_definition
# A way to make `'register_rb_step_definition'` succeed:
runtime = Cucumber::Runtime.new
config = Cucumber::Configuration.new
language = Cucumber::RbSupport::RbLanguage.new(runtime, config)
dsl = Cucumber::RbSupport::RbDsl
dsl.rb_language = language
steps = {}
steps["foo"] = dsl.register_rb_step_definiton(/foo (.+)/, ->(args) { puts args })
# Now I have a 'steps' hash like {"foo" => foo_step_object}
# I can call a step like so:
steps["foo"].invoke(["bar"]) # the argument to invoke is an array or hash
# this will print bar to the console like the step proc instructed
这成功定义并调用了测试,但有一些缺点:
step("foo bar")
之类的内容,而不是写steps["foo"].invoke(["bar"])
。在我当前尝试调用步骤时,将忽略定义中的正则表达式。我一直在研究关于Cucumber的一些讨论,似乎有一种推动力去除使用steps
方法调用步骤的能力。换句话说,所有步骤嵌套都应该通过将代码重构为单独的方法来完成,而不是通过引用其他步骤来完成。我理解这个概念的灵感,但我仍然设想一个用例:
如果Cucumber使用cucumber
shell命令运行,这基本上就是这样的,尽管它要求所有步骤都在一个功能中运行。场景。如果我的应用程序只需要“步骤”,但需要定义全局“功能”和“场景”,那么就这样吧,但我仍然只想使用Ruby而不是转向cucumber
shell命令。
答案 0 :(得分:2)
这是一个对我有用的例子,手动定义和调用步骤:
require 'cucumber' # must require everything; otherwise Configuration cannot be initialized
config = Cucumber::Configuration.new
dsl = Object.new.extend(Cucumber::RbSupport::RbDsl)
rb_language = Cucumber::RbSupport::RbLanguage.new(:unused, config)
step_search = Cucumber::StepMatchSearch.new(rb_language.method(:step_matches), config)
dsl.Given(/hello (.*)/) { |foo| puts "argument given was: #{foo}" }
match = step_search.call('hello world').first
match.step_definition.invoke(match.args) # => argument given was: world
它也会引发冗余或模糊步骤定义的异常:
dsl.Given(/hello (.*)/) { }
dsl.Given(/(.*) world/) { }
step_search.call('hello world')
# => Cucumber::Ambiguous: Ambiguous match of "hello world"
如果您还想要包含实际的功能文件或步骤定义文件,但不希望它们被包含在内,那么请记住,在没有任何参数的情况下初始化Configuration
会自动加载一些文件夹:
config = Cucumber::Configuration.new
config.autoload_code_paths
# => ["features/support", "features/step_definitions"]
config = Cucumber::Configuration.new(autoload_code_paths: [])
config.autoload_code_paths
# => []
答案 1 :(得分:0)
你想要的是
require 'cucumber'
require 'path_to_step_defs.rb'
这样做只会加载文件path_to_step_defs.rb
一次,而且只加载一次。然后,您不需要load_step_definitions
方法,因为脚本文件已经加载了它所需的内容。