我想在运行任意RSpec测试之前执行一些代码,但仅限于要测试的示例组在特定目录中或携带特定标记的情况。
例如,如果我有以下组:
## spec/file_one.rb
describe "Spec One - A group which needs the external app running", :external => true do
describe "Spec Two - A group which does not need the external app running" do
## spec/file_two.rb
describe "Spec Three - A group which does NOT need the external app running" do
## spec/always_run/file_three.rb
describe "Spec Four - A group which does need the external app running"
然后,当测试运行包含Spec One或Spec Four时,我希望代码只能执行。
当我可以依赖文件名时这相对容易,但依赖于标签则更难。如何查看将运行哪些文件示例,然后检查其标签?
答案 0 :(得分:2)
我只是有这样的支持设置:
PID_FILE = File.join(Rails.root, "tmp", "pids", "external.pid")
def read_pid
return nil unless File.exists? PID_FILE
File.open(PID_FILE).read.strip
end
def write_pid(pid)
File.open(PID_FILE, "w") {|f| f.print pid }
end
def external_running?
# Some test to see if the external app is running here
begin
!!Process.getpgid(read_pid)
rescue
false
end
end
def start_external
unless external_running?
write_pid spawn("./run_server")
# Maybe some wait loop here for the external service to boot up
end
end
def stop_external
Process.kill read_pid if external_running?
end
RSpec.configure do |c|
before(:each) do |example|
start_external if example.metadata[:external]
end
after(:suite) do
stop_external
end
end
标记为:external
的每个测试都会尝试启动外部进程(如果尚未启动)。因此,第一次运行需要它的测试时,将启动该进程。如果未运行带有标记的测试,则永远不会引导该进程。然后,套件通过在关闭过程中终止进程来自行清理。
这样,您不必预先处理测试列表,您的测试不会相互依赖,之后会自动清理您的外部应用程序。如果外部应用程序在测试套件有机会调用它之前运行,它将读取pid文件并使用现有实例。
您可以解析示例的全名,并确定是否需要外部应用程序进行更“神奇”的设置,而不是依赖metadata[:external]
,但这对我来说有点臭;示例描述适用于人类,而不适用于要解析的规范套件。