我的任务是在运行一系列最小的测试脚本之前锁定开发数据库,然后在所有测试完成后解锁数据库。
所有测试都是通过使用rake test执行Rake文件来运行的。
最有效的方法是什么?
答案 0 :(得分:0)
我认为1.是要走的路。然后在Rakefile中,您可以将每个测试都视为相同,如果每个测试都是独立的或锁定共享资源(在您的情况下是一个数据库),那么您就拥有了一个非常好的可解决的测试套件。
当然,您并不想实际复制粘贴锁定/解锁代码。我认为在测试用例之间共享代码的方法是定义一个自定义模块,如文档建议(http://docs.seattlerb.org/minitest/),并在需要锁定数据库的测试中包含该模块,或者使测试用例继承自一个继承自Minitest :: Test的自定义类,您可以将它们放入测试助手中。
编辑 - 代码:
module LockDb
#Replace this with the path to your actual database
DB_FILE = 'db'
def setup
@f = File.open(DB_FILE, 'r+')
@f.flock(File::LOCK_EX)
end
def teardown
@f.flock(File::LOCK_UN)
end
end
您可以将这个包含在要锁定数据库的测试类中,如下所示:
class TestMeme < Minitest::Test
include LockDb
#Your tests
end
要查看它是否有效,您可以设置一个简单的测试无框架脚本,如下所示,并通过在多个窗口中运行它来获得乐趣(确保在运行之前touch db
以便它可以打开文件它预计):
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
module LockDb
#Replace this with the path to your actual database
DB_FILE = 'db'
def setup
@f = File.open(DB_FILE, 'r+')
@f.flock(File::LOCK_EX)
end
def teardown
@f.flock(File::LOCK_UN)
end
end
extend LockDb
#The setup hook is run before each test method in minitest
setup
puts "Locked"
#This would be one of your test methods
puts "Press Enter to unlock"
gets
#^This would be the end of one of your test methods
#The teardown hook is run before each test method in minitest
teardown
puts "Unlocked"
评论:
如果您已经拥有这些方法,它们将覆盖模块提供的方法,因此您需要修改那些已定义的方法来调用super
,以便调用模块提供的版本。 (拆分模块是没有意义的,逻辑上,你总是需要调用整个模块)
如果这似乎太多了,你也可以尝试采用rake路线,例如
namespace :old do
#put the old :test definition here
end
task :teardown => 'old:test' do
#the code
end
task 'old:test' => :setup
task :setup do
#the code
end
task :test => :teardown