0

我想在运行任意 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"

然后我希望只有在测试运行包含规范一或规范四时才执行代码。

当我可以依赖文件名时,这相对容易做到,但在依赖标签时更难。如何检查将运行哪些文件示例,然后检查它们的标签?

4

1 回答 1

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]您,不如解析示例的全名并确定它是否需要外部应用程序来进行更“神奇”的设置,但这对我来说有点臭;示例描述是针对人类的,而不是供规范套件解析的。

于 2013-04-11T05:10:29.977 回答