使用SQLite in memory提高测试代码效率

对于需要进行持续集成的大型项目来说,运行测试代码的花费就显得尤为重要,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

This entry was posted in 性能, 数据库, 测试. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

无觅相关文章插件,快速提升流量