Làm cách nào để tải dữ liệu db: seed vào cơ sở dữ liệu thử nghiệm một cách tự động?


122

Tôi đang cố gắng sử dụng cách chuẩn mới để tải dữ liệu hạt giống trong Rails 2.3.4+, db:seedtác vụ rake.

Tôi đang tải dữ liệu liên tục, dữ liệu này được yêu cầu để ứng dụng của tôi thực sự hoạt động chính xác.

Cách tốt nhất để thực hiện db:seednhiệm vụ trước khi kiểm tra, để dữ liệu được điền trước là gì?

Câu trả lời:


120

Tác db:seedvụ rake chủ yếu chỉ tải db/seeds.rbscript. Do đó chỉ cần thực thi tệp đó để tải dữ liệu.

load "#{Rails.root}/db/seeds.rb"

# or

Rails.application.load_seed

Việc đặt ở đâu phụ thuộc vào khung thử nghiệm bạn đang sử dụng và liệu bạn có muốn tải nó trước mỗi lần thử nghiệm hay chỉ một lần khi bắt đầu. Bạn có thể đặt nó trong một setupcuộc gọi hoặc trong một test_helper.rbtệp.


4
Tôi thích sự đơn giản, nhưng vì lý do nào đó mà việc thêm dòng này vào của tôi test_helper.rbkhông phù hợp với tôi mặc dù stackoverflow.com/a/1998520/68210 đã làm.
Daniel X Moore

37
Trong các phiên bản mới hơn của đường ray bạn có thể làm: Rails.application.load_seed
Steve

@Steve cảm ơn bạn - bạn có biết đặt Rails.application.load_seed ở đâu nếu một người đang sử dụng rspec / capybarra, chẳng hạn?
BKSpurgeon

1
@BKSpurgeon Tôi tải dữ liệu hạt giống khá nhiều trong các ứng dụng của mình vì nó yêu cầu dữ liệu cụ thể để chạy và nhà máy quá phức tạp. Tôi đã đặt Rails.application.load_seedngay dưới require 'rspec/rails' tệp rails_helper của mình. Nếu bạn đang sử dụng database_cleaner đá quý - nó sẽ đòi hỏi một chút tinh chỉnh để đảm bảo bạn không bị mất dữ liệu dòng dõi ngươi sau mỗi lần thử nghiệm và bạn có thể thấy rằng trong tài liệu của đá quý nó tự
MageeWorld

Trong Rails 5.x, tôi đã thêm dòng này vào test/test_helper.rbsau require 'rails/test_help'dòng hiện có
Andrew

87

Tôi muốn nói rằng nó phải là

namespace :db do
  namespace :test do
    task :prepare => :environment do
      Rake::Task["db:seed"].invoke
    end
  end
end

Vì db: test: load không được thực thi nếu bạn có config.active_record.schema_format =: sql (db: test: clone_ architecture is)


4
Chạy rake với --traceđã giúp tôi hiểu cách hoạt động của nó.
Jared Beck,

4
@BookOfGreg Tôi có nó trong lib / nhiệm vụ / test_seed.rake mà tôi tạo ra bản thân mình
Eugene Bolshakov

6
Tại sao không chỉ cái này? task 'db:test:prepare' => 'db:seed'
Carson Reinke

3
Đối với Rails 4.0.0, thêm lần cuối cùng ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])trướcRake::Task["db:seed"].invoke
janic_

3
@CarsonReinke - bởi vì sau đó môi trường khi db:seedchạy rất development... kỳ lạ.
denishaskin

17

Đặt một cái gì đó như thế này trong lib / task / test_seed.rake sẽ gọi tác vụ hạt giống sau db: test: load:

namespace :db do
  namespace :test do
    task :load => :environment do
      Rake::Task["db:seed"].invoke
    end
  end
end

15

Tôi tin rằng bình luận của Steve ở trên là câu trả lời chính xác. Bạn có thể sử dụng Rails.application.load_seedđể tải dữ liệu hạt giống vào envoironment thử nghiệm của mình. Tuy nhiên, khi nào và tần suất tải dữ liệu này phụ thuộc vào một số điều sau:

Sử dụng Minitest

Không có cách nào thuận tiện để chạy tệp này một lần trước tất cả các thử nghiệm (xem vấn đề Github này ). Bạn sẽ cần tải dữ liệu một lần trước mỗi lần kiểm tra, có thể là trong phương pháp thiết lập tệp kiểm tra của bạn:

# test/models/my_model_test.rb
class LevelTest < ActiveSupport::TestCase

  def setup
    Rails.application.load_seed
  end

  # tests here...

end

Sử dụng RSpec

Sử dụng before(:all)phương pháp của RSpec để tải dữ liệu hạt giống cho tất cả các thử nghiệm cho mô hình này:

describe MyModel do
  before(:all) do
  Rails.application.load_seed
end

describe "my model..." do
  # your tests here
end

Hi vọng điêu nay co ich.


2
Câu trả lời tốt nhất cho đến nay
Yuri Ghensev

Tôi làm điều gì đó tương tự, ngoại trừ việc tôi đang gọi nó vào before(:suite)thay vì before(:all). Đã đăng một câu trả lời riêng để bao gồm mã được định dạng.
Mark Schneider

3

Chúng tôi đang gọi db: seed như một phần của db: test: chuẩn bị, với:

Rake::Task["db:seed"].invoke

Bằng cách đó, dữ liệu hạt giống được tải một lần cho toàn bộ quá trình chạy thử nghiệm chứ không phải một lần cho mỗi lớp thử nghiệm.


4
Bạn đã tạo một công việc db: test: chuẩn bị mới để làm điều đó? Bạn có thể đăng mã?
Luke Francl

3

Đối với những người sử dụng ngân hàng hạt giống, nó thay đổi cách hạt giống được tải, vì vậy có thể bạn không thể / không muốn sử dụng load ...giải pháp được cung cấp ở đây.

Và chỉ cần đưa Rake::Task['db:seed'].invokevào test_helper đã dẫn đến:

Don't know how to build task 'db:seed' (RuntimeError)

Nhưng khi chúng tôi thêm load_tasks trước đó, nó hoạt động:

MyApp::Application.load_tasks
Rake::Task['db:seed'].invoke

2

Thêm Rake::Task["db:seed"].invokevào db:test:preparenhiệm vụ cào không làm việc với tôi. Nếu tôi chuẩn bị cơ sở dữ liệu vớirake db:test:prepare và sau đó nhập bảng điều khiển trong môi trường thử nghiệm, tất cả các hạt giống của tôi đều ở đó. Tuy nhiên, các hạt giống không tồn tại giữa các thử nghiệm của tôi.

Thêm load "#{Rails.root}/db/seeds.rb" vào phương pháp thiết lập của tôi hoạt động tốt.

Tôi rất muốn tải những hạt giống này tự động và liên tục, nhưng tôi vẫn chưa tìm ra cách để làm điều đó!


0

Dựa trên câu trả lời của Matt, nếu đi theo loại lộ trình đó, tôi khuyên bạn nên gọi Rails.application.load_seedtrong một before(:suite)khối rspec_helper.rbthay vì gọibefore(:all) khối trong bất kỳ tệp nào. Bằng cách đó, mã khởi tạo chỉ được gọi một lần cho toàn bộ bộ thử nghiệm thay vì một lần cho mỗi nhóm thử nghiệm.

rspec_helper.rb:

RSpec.configure do |config|
  ...
  config.before(:suite) do
    Rails.application.load_seed
  end
  ...
end
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.