2011-07-05 17 views
5

Tôi đang sử dụng Ruby on Rails 3 và viết các bài kiểm tra nhưng nó quá chậm. Có một số cấu hình hoặc công cụ tốt để làm cho nhanh hơn không?Làm cách nào để chạy thử nghiệm trên RoR nhanh hơn?

+3

Nếu bạn đang sử dụng RSpec bạn có thể khởi động với [Spork] (http://rubygems.org/ đá quý/spork) –

Trả lời

2

Khi @eml nói, nếu bạn đang sử dụng RSpec, bạn có thể sử dụng Spork. Điều này về cơ bản cháy lên môi trường (đó là một phần chậm) và sau đó giữ nó xung quanh, forking mỗi khi bạn chạy thông số kỹ thuật của bạn.

Để có giải pháp tổng quát hơn cho vấn đề "môi trường luôn được tải" có thể cài đặt rails-sh và chạy thử nghiệm của bạn từ bên trong trình bao.

Lưu ý phụ: Ruby 1.9.3 sẽ giảm nhẹ vấn đề này một chút khi thời gian yêu cầu đã được tối ưu hóa.

4

Có lẽ tốc độ tăng lớn nhất đến từ việc cẩn thận không để nhấn cơ sở dữ liệu trừ khi bạn cần. Mock đối tượng thay vì lấy chúng từ cơ sở dữ liệu, và/hoặc (nếu bạn đang sử dụng cô gái nhà máy ví dụ) sử dụng Factory.build (: stuff) thay vì Factory (: stuff) bất cứ nơi nào có thể. Chỉ khi bạn đã thực hiện điều đó, bạn nên bắt đầu cố gắng tối ưu hóa thêm với spork

Cập nhật: Cá nhân, tôi cũng bắt đầu nghĩ rằng bạn không nên bị treo nhanh về tốc độ thử nghiệm của mình. Nhanh hơn rõ ràng là tốt hơn, nhưng khi một ứng dụng phát triển, bộ thử nghiệm sẽ phát triển, và tuy nhiên cẩn thận bạn là nó cuối cùng sẽ trở nên chậm hơn bạn muốn. Tôi đang đến để dựa nhiều hơn và nhiều hơn nữa trên đá quý autotest mà kiểm tra việc thay đổi mã và hoạt động trong nền (guard-rspec hiện một công việc tương tự). Vào thời điểm ứng dụng của bạn đạt đến 1000 bài kiểm tra, bạn sẽ không muốn đợi toàn bộ bộ phần mềm hoàn thành mỗi khi bạn thực hiện thay đổi, tuy nhiên, các thử nghiệm sẽ chạy nhanh.

+0

Lời khuyên tuyệt vời. Tôi thực sự đánh giá cao mã nơi bạn có thể nói với nhà phát triển đã quan tâm đến lĩnh vực này. Tôi chỉ báo trước, tôi sẽ không nhất thiết phải nhấn mạnh vào các bài kiểm tra nhanh như là một điều kiện tiên quyết cho Spork. Đặc biệt khi thực hiện một tập hợp nhỏ các thông số kỹ thuật chọn thường xuyên, nơi tải môi trường đường ray có thể trở thành một trở kháng thực sự. –

+0

Điểm công bằng - Tôi đoán đó là ngựa cho các khóa học thực sự - Tôi đã phản ứng với một trong những câu trả lời khác dường như gợi ý rằng spork là một loại đạn bạc ... Tôi không cho rằng đây là những gì người viết dự định, nhưng tôi nghĩ rằng đó là một chút gây hiểu nhầm – chrispanda

2

IMHO phần chậm chính của thử nghiệm là cấu hình mặc định của đồ đạc. Nếu cấu hình của bạn là (trong test/test_helper.rb):

class ActiveSupport::TestCase 
    self.use_transactional_fixtures = false 
    self.pre_loaded_fixtures = false 
    self.use_instantiated_fixtures = true 

sau đó trước mỗi phương pháp thử nghiệm cơ sở dữ liệu thử nghiệm của bạn được làm sạch từ dữ liệu cũ, tất cả các bảng được dân cư, tất cả các hồ sơ được đọc vào bộ nhớ.

Nếu bạn thay đổi các thiết lập để điều ngược lại:

class ActiveSupport::TestCase 
    self.use_transactional_fixtures = true 
    self.pre_loaded_fixtures = true 
    self.use_instantiated_fixtures = false 

sau đó cơ sở dữ liệu được tái tạo một lần duy nhất cho mỗi tập tin kiểm tra, và bạn chỉ tải các hồ sơ bạn thực sự cần trong mỗi phương pháp thử nghiệm.

Tùy thuộc vào kích thước của tập dữ liệu thử nghiệm của bạn cho dù bạn thấy thời gian tạo cơ sở dữ liệu thử nghiệm có thể chấp nhận được hay không. Khi tôi có một số dữ liệu thử nghiệm khá lớn, tôi chỉ nạp các đồ đạc một lần, trước toàn bộ bộ thử nghiệm, nhưng dự án đó là (là) trong Rails 1, và tôi đã sửa đổi rất nhiều, vì vậy tôi không thể biết cách làm trong Rails 3 (ít nhất là cho đến khi vấn đề bắt đầu gây đau đớn trong một số dự án mới);

Có một cuộc thảo luận không bao giờ cho dù các thử nghiệm có nên nhấn vào cơ sở dữ liệu hay không. Nếu bạn tin rằng họ nên (kể từ khi hợp tác cơ sở dữ liệu cũng nên được kiểm tra), sau đó bạn có thể kiểm tra cho dù chỉ cần thiết lập các thông số này giúp bạn (hoặc bất cứ ai đọc những câu trả lời).

0

Cố gắng phát triển để hầu hết các thử nghiệm của bạn có thể được thực thi mà không cần tải toàn bộ khung ứng dụng Rails. Trong helper spec của bạn, bỏ qua tải môi trường hoặc rpec/đường ray nếu chỉ kiểm tra nhanh đang được thực hiện, một cái gì đó giống như ...

# /spec/spec_helper.rb 
if RSpec.configuration.inclusion_filter[:fast] 
    # Setup required for fast tests in particular (if any) 
    # ... 
else 
    ENV["RAILS_ENV"] ||= 'test' 
    require File.expand_path("../../config/environment", __FILE__) 
    require 'rspec/rails' 

    Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} 
end 

RSpec.configure do |config| 
    # ... 

    unless RSpec.configuration.inclusion_filter[:fast] 
    # If you're not using ActiveRecord, or you'd prefer not to run each of your 
    # examples within a transaction, remove the following line or assign false 
    # instead of true. 
    config.use_transactional_fixtures = true 
    end 
end 

Để đánh dấu một thử nghiệm là "nhanh", thêm tùy chọn , :fast => true lời kêu gọi của nó it hoặc đến một cuộc gọi xung quanh describe.

Để chỉ chạy thử nghiệm nhanh, hãy thực thi rspec --tag fast từ trình bao lệnh của bạn. Có thể khó để tìm ra cách cấu trúc mã của bạn để các bài kiểm tra có thể chạy riêng với Rails (và dĩ nhiên, bạn vẫn muốn có các bài kiểm tra chức năng và tích hợp không chạy riêng).

Một thủ thuật trong kho vũ khí của tôi là tránh viết mã trực tiếp trên mô hình ActiveRecord hoặc các lớp khác, và thích viết nó lên mô-đun mixin thay thế. Bạn có thể kiểm tra mô-đun mixin bằng cách xác định Chủ thể là một đối tượng được mở rộng bởi mô đun đó ...

describe 'MyModule', :fast => true 
    subject{ Object.new.tap{|o| o.extend MyModule} } 

    it 'does something' do 
    # ... 
    end 
end 
Các vấn đề liên quan