对于需要进行持续集成的大型项目来说,运行测试代码的花费就显得尤为重要,Chris Roos在这篇帖子里介绍了一种通过使用SQLite数据库来 提高测试代码运行效率的方法。
首先你需要安装SQLite3以及sqlite3-ruby gem,然后修改database.yml:
test:
adapter: sqlite3
database: ":memory:"
但是这样有一个问题,由于SQLite数据库保存在内存中,因此必须在每次执行单元测试之前首先生成数据库的大纲,不过不用担心,Chris Roos已经提供了一段现成的代码,将它加到你的environment.rb就可以了:
def in_memory_database?
ENV["RAILS_ENV"] == "test" and
ActiveRecord::Base.connection.class == ActiveRecord::ConnectionAdapters::SQLite3Adapter and
Rails::Configuration.new.database_configuration['test']['database'] == ':memory:'
end
if in_memory_database?
puts "creating sqlite in memory database"
load "#{RAILS_ROOT}/db/schema.rb" # use db agnostic schema by default
# ActiveRecord::Migrator.up('db/migrate') # use migrations
end
不过要注意,以上代码最好加在”# Include your application configuration below”这一行之后,因为说不准后面的配置有可能就会用到数据库。
这段代码使用db/schema.rb来初始化数据库,因此你最好先执行下面这条命令,以保证schema.rb与数据库保持同步(当然你也可以使用db:migrate):
rake db:migrate:dump
现在在执行下rake test,看看速度是不是快了不少,下面是我找的一个小测试程序的运行结果:
sqlite in memory:
unit tests: 0.14s
functional tests: 0.59s
mysql:
unit tests: 1.16s
functional tests: 1.81s
如果你觉得这样还是有些麻烦,不要紧,Geoffrey Grosenbach已经为你准备好了一个插件,你只需要动手改一下database.yml就成了。
更新:如果不想每次都看到那一堆数据库创建信息,那么只需在加载schema.rb之前,将ActiveRecord::Schema.verbose置为false即可:
if in_memory_database?
verbose = ActiveRecord::Schema.verbose
ActiveRecord::Schema.verbose = false
puts "creating sqlite in memory database"
load "#{RAILS_ROOT}/db/schema.rb" # use db agnostic schema by default
ActiveRecord::Schema.verbose = verbose
end
