在 Rails 引擎中 Rspec 是否可以使用来自另一个引擎的 Rspec 支持系统助手?
In a Rails engine Is it possible for Rspec to make use of Rspec support system helpers from another engine?
假设 Rails engine_one 具有规范支持文件 engine_one/spec/support/system/order_functions.rb
,包含支持各种订单系统测试的功能,例如模拟登录用户、添加产品到订单等,并包含在测试订单处理等时广泛使用的 log_visitor_in 等方法...
所以现在 engine_two 扩展了 engine_one 的一些订购功能,我希望添加一个新的系统测试,首先必须让访问者登录。那么我如何利用该支持来自 engine_one?
的方法
到目前为止,我已经在虚拟应用程序中安装了引擎
我在 engine_two/lib/engine.rb 中要求 engine_one
我在相关测试中需要支持文件,但找不到,显然我已经将 engine_one 添加到 engine_two.gemspec
engine_two/spec/rails_helper.rb
require 'engine_one' # and any other gems you need
engine_two/lib/engine_two/engine.rb
require 'engine_one'
在相关系统测试中我有以下
engine_two/spec/system/new_payment_methods_spec.rb
require 'rails_helper'
include EngineOne::System
RSpec.describe "order_payment_feature", type: :system do
before do
driven_by(:rack_test)
end
it "has order payment options" do
log_visitor_in
end
end
这会导致以下错误
Failure/Error: include EngineOne::System
NameError:
uninitialized constant EngineOne::System
Did you mean? SystemExit
还有帮手
module System
def log_visitor_in()
administrator = create(:visitor)
visit ccs_cms.login_url
fill_in 'login_name', with: visitor.login_name
fill_in 'Password', with: visitor.password
click_button 'Login'
end
end
我尝试使用 require 而不是 include,但这会导致文件未找到错误
另外,我尝试将包含路径更改为
include EngineOne::Spec::Support::System
导致同样的错误
所以我想我正在寻找正确的路径,但我被卡住了或错过了一些其他方式来包含帮助程序。
这些是 Rails 7 个引擎。
当您 require
一个文件时,ruby 会根据 $LOAD_PATH
中的路径搜索它; spec/ 或 test/ 不是其中的一部分。
app
目录是rails中的特殊目录,任何子目录自动成为autoload_paths
的一部分。可以在这里看到自动加载路径 ActiveSupport::Dependencies.autoload_paths
.
在 app/*
目录中定义的任何 classes/modules 都可以使用,不需要相应的文件。 Rails v7 使用 zeitwerk
依靠 'file name' 到 'constant name' 的关系自动 load/reload 文件。这就是文件夹映射到命名空间而文件映射到 classes/modules.
的原因
要解决您的问题,请将任何共享代码放在可以用 require
获取的地方。在控制台输入$LOAD_PATH
:
>> $LOAD_PATH
=>
["/home/alex/code/Whosebug/lib",
"/home/alex/code/Whosebug/vendor",
"/home/alex/code/Whosebug/app/channels",
"/home/alex/code/Whosebug/app/controllers",
"/home/alex/code/Whosebug/app/controllers/concerns",
"/home/alex/code/Whosebug/app/helpers",
"/home/alex/code/Whosebug/app/jobs",
"/home/alex/code/Whosebug/app/mailers",
"/home/alex/code/Whosebug/app/models",
"/home/alex/code/Whosebug/app/models/concerns",
"/home/alex/code/Whosebug/engines/question/lib", # <= engine's lib looks good
"/home/alex/code/Whosebug/engines/question/app/components",
"/home/alex/code/Whosebug/engines/question/app/controllers",
"/home/alex/code/Whosebug/engines/question/app/controllers/concerns",
...
将共享文件放在引擎的lib目录下。由于我们在 app
目录之外,rails 不再是老板,任何路径和文件名组合都可以。
# question/lib/testing_support/blah.rb # <= note the filename
module System
def log_visitor_in
administrator = create(:visitor)
visit ccs_cms.login_url
fill_in 'login_name', with: visitor.login_name
fill_in 'Password', with: visitor.password
click_button 'Login'
end
end
现在可以需要该文件了
# test/test_helper.rb or spec/rails_helper.rb
# after environment and rails requires
require "testing_support/blah" # => loads System module
# ...
就是这样,在您的规范中使用它
require 'rails_helper'
RSpec.describe "order_payment_feature", type: :system do
include System # include is for modules; now we have its functions in this spec
before { log_visitor_in }
it 'should accept this answer' do
visit 'questions/71362333'
expect(page).to have_content('accepted')
end
end
此外,无论 $LOAD_PATH
.
是什么,您都可以使用绝对路径以任何方式要求您的文件
require EngineOne::Engine.root + 'spec/support/system/order_functions.rb'
# or something else
Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each { |f| require f }
假设 Rails engine_one 具有规范支持文件 engine_one/spec/support/system/order_functions.rb
,包含支持各种订单系统测试的功能,例如模拟登录用户、添加产品到订单等,并包含在测试订单处理等时广泛使用的 log_visitor_in 等方法...
所以现在 engine_two 扩展了 engine_one 的一些订购功能,我希望添加一个新的系统测试,首先必须让访问者登录。那么我如何利用该支持来自 engine_one?
的方法到目前为止,我已经在虚拟应用程序中安装了引擎 我在 engine_two/lib/engine.rb 中要求 engine_one 我在相关测试中需要支持文件,但找不到,显然我已经将 engine_one 添加到 engine_two.gemspec
engine_two/spec/rails_helper.rb
require 'engine_one' # and any other gems you need
engine_two/lib/engine_two/engine.rb
require 'engine_one'
在相关系统测试中我有以下
engine_two/spec/system/new_payment_methods_spec.rb
require 'rails_helper'
include EngineOne::System
RSpec.describe "order_payment_feature", type: :system do
before do
driven_by(:rack_test)
end
it "has order payment options" do
log_visitor_in
end
end
这会导致以下错误
Failure/Error: include EngineOne::System
NameError:
uninitialized constant EngineOne::System
Did you mean? SystemExit
还有帮手
module System
def log_visitor_in()
administrator = create(:visitor)
visit ccs_cms.login_url
fill_in 'login_name', with: visitor.login_name
fill_in 'Password', with: visitor.password
click_button 'Login'
end
end
我尝试使用 require 而不是 include,但这会导致文件未找到错误 另外,我尝试将包含路径更改为
include EngineOne::Spec::Support::System
导致同样的错误
所以我想我正在寻找正确的路径,但我被卡住了或错过了一些其他方式来包含帮助程序。 这些是 Rails 7 个引擎。
当您 require
一个文件时,ruby 会根据 $LOAD_PATH
中的路径搜索它; spec/ 或 test/ 不是其中的一部分。
app
目录是rails中的特殊目录,任何子目录自动成为autoload_paths
的一部分。可以在这里看到自动加载路径 ActiveSupport::Dependencies.autoload_paths
.
在 app/*
目录中定义的任何 classes/modules 都可以使用,不需要相应的文件。 Rails v7 使用 zeitwerk
依靠 'file name' 到 'constant name' 的关系自动 load/reload 文件。这就是文件夹映射到命名空间而文件映射到 classes/modules.
要解决您的问题,请将任何共享代码放在可以用 require
获取的地方。在控制台输入$LOAD_PATH
:
>> $LOAD_PATH
=>
["/home/alex/code/Whosebug/lib",
"/home/alex/code/Whosebug/vendor",
"/home/alex/code/Whosebug/app/channels",
"/home/alex/code/Whosebug/app/controllers",
"/home/alex/code/Whosebug/app/controllers/concerns",
"/home/alex/code/Whosebug/app/helpers",
"/home/alex/code/Whosebug/app/jobs",
"/home/alex/code/Whosebug/app/mailers",
"/home/alex/code/Whosebug/app/models",
"/home/alex/code/Whosebug/app/models/concerns",
"/home/alex/code/Whosebug/engines/question/lib", # <= engine's lib looks good
"/home/alex/code/Whosebug/engines/question/app/components",
"/home/alex/code/Whosebug/engines/question/app/controllers",
"/home/alex/code/Whosebug/engines/question/app/controllers/concerns",
...
将共享文件放在引擎的lib目录下。由于我们在 app
目录之外,rails 不再是老板,任何路径和文件名组合都可以。
# question/lib/testing_support/blah.rb # <= note the filename
module System
def log_visitor_in
administrator = create(:visitor)
visit ccs_cms.login_url
fill_in 'login_name', with: visitor.login_name
fill_in 'Password', with: visitor.password
click_button 'Login'
end
end
现在可以需要该文件了
# test/test_helper.rb or spec/rails_helper.rb
# after environment and rails requires
require "testing_support/blah" # => loads System module
# ...
就是这样,在您的规范中使用它
require 'rails_helper'
RSpec.describe "order_payment_feature", type: :system do
include System # include is for modules; now we have its functions in this spec
before { log_visitor_in }
it 'should accept this answer' do
visit 'questions/71362333'
expect(page).to have_content('accepted')
end
end
此外,无论 $LOAD_PATH
.
require EngineOne::Engine.root + 'spec/support/system/order_functions.rb'
# or something else
Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each { |f| require f }