作为 TDD 和 Rails 世界的新手,我试图弄清楚如何减少我的规范的运行时间。
我放弃了 Rails 框架的加载,只加载了 ActiveRecord 部分。这有很大帮助(-8s),尽管我仍然想知道是否还有更多我可以做的。
spec 文件有 5 个示例,运行它time rspec path_to_spec.rb
需要 1.7 秒。当我删除 FactoryGirl 并Project.create
改为使用时,我达到了 1.4 秒。
我要测试的是模型的范围和查询组合是否正常。我不确定在这种情况下是否可以使用模拟/存根。
- 有没有办法可以利用模拟/存根功能来测试
next_project
的行为? - 我怎么知道 ActiveRecord 交互时间的限制是多少?我的意思是,在测试 ActiveRecord 模型时,我必须处理 1-2 秒的执行时间吗?
- 关于如何加快速度的任何其他建议?
我正在使用 ruby 1.9.3、rspec 2.1.12、ActiveRecord 3.2.9
我的模型文件:
class Project < ActiveRecord::Base
default_scope where(:is_enabled => true).order(:position)
def self.by_slug(slug)
where(:slug => slug).first
end
def find_neighbors
Neighbors.new(previous_project, next_project)
end
private
def previous_project
Project.where("position < ?", position).last
end
def next_project
Project.where("position > ?", position).first
end
end
Neighbors = Struct.new(:previous, :next)
我的规格文件:
require 'active_record'
require 'yaml'
require 'factory_girl'
require './app/models/project'
dbconfig = YAML::load(File.open('./config/database.yml'))
ActiveRecord::Base.establish_connection(dbconfig["test"])
FactoryGirl.define do
factory :project do
slug { name.parameterize }
sequence(:position, 1)
is_enabled true
end
end
describe Project do
before(:all) do
@first_project = FactoryGirl.create(:project, name: "First Project")
@second_project_disabled = FactoryGirl.create(:project, name: "Second Project", is_enabled: false)
@third_project = FactoryGirl.create(:project, name: "Third Project")
@fourth_project_disabled = FactoryGirl.create(:project, name: "Fourth Project", is_enabled: false)
@fifth_project = FactoryGirl.create(:project, name: "Fifth Project")
end
after(:all) do
projects = [@first_project, @second_project_disabled, @third_project, @fourth_project_disabled, @fifth_project]
projects.each { |p| p.delete }
end
context "when requesting a project by URL slug" do
it "should return that project if it is enabled" do
Project.by_slug(@third_project.slug).should eql(Project.find(@third_project.id))
end
it "should not return the project if it is not enabled" do
Project.by_slug(@fourth_project_disabled.slug).should be_nil
end
end
context "when getting first project" do
it "should have a reference only to the next project enabled" do
neighbors = @first_project.find_neighbors
neighbors.previous.should be_nil
neighbors.next.should eql(Project.find(@third_project.id))
end
end
# 2 more examples similar to the last one
end