TDD と Rails の世界の初心者である私は、仕様の実行時間を短縮する方法を見つけようとしています。
Rails フレームワークの読み込みをやめて、ActiveRecord 部分だけを読み込みます。これは非常に役に立ちました (-8 秒) が、他にできることがあるかどうかはまだ疑問に思っています。
スペック ファイルには 5 つの例があり、実行にtime rspec path_to_spec.rb
は 1.7 秒かかります。FactoryGirlを外してProject.create
代わりに使ったら1.4sになりました。
テストしたいのは、モデルのスコープとクエリの組み合わせが正常に機能するかどうかです。この場合、モッキング/スチューブを使用できるかどうかはわかりません。
- たとえば、
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