如何通过RSpec的files_or_directories_to_run加载Rails外部共享测试文件?
我懂你想在当前Rails项目里复用其他项目的共享RSpec测试用例的需求,之前硬改源码确实太折腾了,而且升级RSpec就会失效,完全没必要。下面给你几个规范的实现方式,逐个试试:
方式1:直接通过命令行/.rspec指定多路径运行
其实你之前误解了files_or_directories_to_run的用法——它是RSpec内部存储运行路径的属性,不是命令行参数。正确的做法是直接把外部测试路径作为运行参数传给RSpec:
命令行直接运行
# 同时运行项目内spec目录和外部共享测试目录 bundle exec rspec spec/ ../shared-test-suite/
固定到.rspec文件
如果不想每次都敲长命令,直接在项目根目录的.rspec文件末尾添加外部路径即可,比如:
--color --format documentation ../shared-test-suite/
这样以后运行bundle exec rspec时,会自动同时执行项目内spec和指定的外部测试目录。
方式2:在配置文件中加载外部测试文件
如果需要更灵活的控制(比如只加载特定类型的测试文件),可以在spec/rails_helper.rb或spec/spec_helper.rb里通过代码加载外部文件:
RSpec.configure do |config| # 加载外部共享目录下所有以_spec.rb结尾的测试文件 # 注意路径可以是绝对路径,也可以是相对于项目根目录的相对路径 Dir.glob('../shared-test-suite/**/*_spec.rb').each do |shared_test_file| require shared_test_file end end
添加这段代码后,启动RSpec时会自动加载这些外部测试文件并执行。
方式3:封装共享示例组(更推荐的复用方式)
如果只是想复用特定的测试逻辑,而不是整个测试文件,建议把共享逻辑封装成RSpec的shared_examples或shared_context,这样可以在项目的测试文件中按需引用,更可控:
1. 在共享目录创建复用文件
比如../shared-test-suite/shared_examples/authentication.rb:
RSpec.shared_examples "authenticated endpoint" do it "redirects unauthenticated requests" do get :index expect(response).to redirect_to(new_session_path) end end
2. 在项目测试文件中引用
# 先加载共享文件 require '../shared-test-suite/shared_examples/authentication' RSpec.describe DashboardController do # 引用共享示例组 include_examples "authenticated endpoint" end
为什么之前的配置没生效?
你之前尝试的--files_or_directories_to_run不是RSpec的命令行参数,而直接调用RSpec.configure里的files_or_directories_to_run=也不会生效——因为RSpec启动时会优先解析命令行参数和.rspec文件的配置,覆盖这个内部属性的值,所以这种方式行不通。
内容的提问来源于stack exchange,提问作者Florian Eck

