จะโหลดข้อมูล db: seed ลงในฐานข้อมูลทดสอบโดยอัตโนมัติได้อย่างไร?


122

ฉันกำลังพยายามใช้วิธีการโหลดข้อมูลเมล็ดพันธุ์มาตรฐานใหม่ใน Rails 2.3.4+ ซึ่งเป็นไฟล์ db:seedงานคราด

ฉันกำลังโหลดข้อมูลคงที่ซึ่งจำเป็นสำหรับแอปพลิเคชันของฉันเพื่อให้ทำงานได้อย่างถูกต้อง

วิธีใดเป็นวิธีที่ดีที่สุดในdb:seedการเรียกใช้งานก่อนการทดสอบดังนั้นข้อมูลจึงถูกเติมไว้ล่วงหน้า

คำตอบ:


120

db:seedงานคราดหลักเพียงแค่โหลดdb/seeds.rbสคริปต์ ดังนั้นเพียงเรียกใช้ไฟล์นั้นเพื่อโหลดข้อมูล

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

# or

Rails.application.load_seed

ตำแหน่งที่จะขึ้นอยู่กับกรอบการทดสอบที่คุณใช้และคุณต้องการให้โหลดก่อนการทดสอบทุกครั้งหรือเพียงครั้งเดียวในตอนเริ่มต้น คุณสามารถวางไว้ในการsetupโทรหรือในtest_helper.rbไฟล์


4
ฉันชอบความเรียบง่าย แต่ด้วยเหตุผลบางอย่างการเพิ่มบรรทัดนี้ไปtest_helper.rbยังไม่ได้ผลสำหรับฉันแม้ว่าจะทำstackoverflow.com/a/1998520/68210ก็ตาม
Daniel X Moore

37
ในรางเวอร์ชันใหม่กว่าคุณสามารถทำได้: Rails.application.load_seed
Steve

@Steve ขอบคุณ - คุณรู้หรือไม่ว่าจะวาง Rails.application.load_seed ไว้ที่ไหนถ้ามีคนใช้ rspec / capybarra เช่น?
BKSpurgeon

1
@BKSpurgeon ฉันโหลดข้อมูลเมล็ดพันธุ์ในแอปพลิเคชันของฉันค่อนข้างน้อยเพราะต้องใช้ข้อมูลเฉพาะในการรันและโรงงานก็ซับซ้อนเกินไป ฉันใส่ไว้Rails.application.load_seedใต้require 'rspec/rails' ไฟล์ rail_helper ของฉัน หากคุณใช้ database_cleaner gem - จะต้องมีการปรับแต่งเล็กน้อยเพื่อให้แน่ใจว่าคุณจะไม่สูญเสียข้อมูลเมล็ดพันธุ์ของคุณหลังจากการทดสอบแต่ละครั้งและคุณจะพบว่าในเอกสารของอัญมณีนั้นเป็นของตัวเอง
MageeWorld

ใน Rails 5.x ฉันเพิ่มสิ่งนี้เข้าไปtest/test_helper.rbหลังrequire 'rails/test_help'บรรทัดที่มีอยู่
Andrew

87

ฉันว่ามันควรจะเป็น

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

เนื่องจากไม่ดำเนินการ db: test: load หากคุณมี config.active_record.schema_format =: sql (db: test: clone_structure is)


4
การใช้คราดด้วย--traceช่วยให้ฉันเข้าใจวิธีการทำงานนี้
Jared Beck

4
@BookOfGreg ฉันมีใน lib / งาน / test_seed.rake ที่ฉันสร้างขึ้นเอง
Eugene Bolshakov

6
ทำไมไม่แค่นี้? task 'db:test:prepare' => 'db:seed'
Carson Reinke

3
สำหรับ Rails 4.0.0 สุดท้ายเพิ่มActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])ก่อนRake::Task["db:seed"].invoke
ม.ค. _

3
@CarsonReinke - เพราะตอนนั้นสภาพแวดล้อมเมื่อdb:seedวิ่งdevelopment...
denishaskin

17

การใส่สิ่งนี้ใน lib / งาน / test_seed.rake ควรเรียกใช้งาน seed หลัง db: test: load:

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

15

ฉันเชื่อว่าความคิดเห็นของสตีฟข้างต้นน่าจะเป็นคำตอบที่ถูกต้อง คุณสามารถใช้Rails.application.load_seedเพื่อโหลดข้อมูลเมล็ดพันธุ์ลงในสภาพแวดล้อมการทดสอบของคุณ อย่างไรก็ตามข้อมูลนี้จะโหลดเมื่อใดและบ่อยเพียงใดขึ้นอยู่กับบางสิ่ง:

ใช้ Minitest

ไม่มีวิธีที่สะดวกในการเรียกใช้ไฟล์นี้ก่อนการทดสอบทั้งหมด (ดูปัญหา Github นี้ ) คุณจะต้องโหลดข้อมูลหนึ่งครั้งก่อนการทดสอบแต่ละครั้งซึ่งน่าจะเป็นวิธีการตั้งค่าของไฟล์ทดสอบของคุณ:

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

  def setup
    Rails.application.load_seed
  end

  # tests here...

end

ใช้ RSpec

ใช้before(:all)วิธีของ RSpec เพื่อโหลดข้อมูลเมล็ดพันธุ์สำหรับการทดสอบทั้งหมดสำหรับรุ่นนี้:

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

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

หวังว่านี่จะช่วยได้


2
คำตอบที่ดีที่สุดจนถึงตอนนี้
Yuri Ghensev

ฉันทำบางสิ่งบางอย่างที่คล้ายกันยกเว้นว่าผมกล่าวอ้างไว้ในแทนbefore(:suite) before(:all)โพสต์คำตอบแยกต่างหากเพื่อรวมโค้ดที่จัดรูปแบบ
Mark Schneider

3

เรากำลังเรียกใช้ db: seed เป็นส่วนหนึ่งของ db: test: เตรียมด้วย:

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

ด้วยวิธีนี้ข้อมูลเมล็ดพันธุ์จะถูกโหลดหนึ่งครั้งสำหรับการทดสอบทั้งหมดไม่ใช่หนึ่งครั้งต่อคลาสทดสอบ


4
คุณสร้างฐานข้อมูลใหม่: ทดสอบ: เตรียมงานเพื่อทำสิ่งนั้นหรือไม่ คุณสามารถโพสต์รหัส?
Luke Francl

3

สำหรับผู้ที่ใช้ seedbank จะเปลี่ยนวิธีโหลดเมล็ดดังนั้นคุณอาจไม่สามารถ / ไม่ต้องการใช้load ...โซลูชันที่ให้ไว้ที่นี่

และเพียงแค่ใส่Rake::Task['db:seed'].invokeเข้าไปใน test_helper ส่งผลให้:

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

แต่เมื่อเราเพิ่ม load_tasks ก่อนหน้านั้นมันใช้งานได้:

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

2

เพิ่มRake::Task["db:seed"].invokeไปdb:test:prepareงานคราดไม่ทำงานสำหรับฉัน ถ้าฉันเตรียมฐานข้อมูลด้วยrake db:test:prepareแล้วเข้าสู่คอนโซลภายในสภาพแวดล้อมการทดสอบเมล็ดพันธุ์ทั้งหมดของฉันก็อยู่ที่นั่น อย่างไรก็ตามเมล็ดไม่คงอยู่ระหว่างการทดสอบของฉัน

เพิ่ม load "#{Rails.root}/db/seeds.rb"แม้ว่าการวิธีการตั้งค่าของฉันก็ใช้ได้ดี

ฉันชอบที่จะให้เมล็ดเหล่านี้โหลดโดยอัตโนมัติและคงอยู่ แต่ฉันยังไม่พบวิธีที่จะทำ!


0

จากคำตอบของ Matt หากใช้เส้นทางแบบนั้นฉันขอแนะนำให้โทรRails.application.load_seedเข้าไปในbefore(:suite)บล็อกrspec_helper.rbแทนที่จะเป็นในไฟล์before(:all)บล็อกในไฟล์ใด ๆ วิธีนี้จะเรียกใช้รหัสการเพาะปลูกเพียงครั้งเดียวสำหรับชุดทดสอบทั้งหมดแทนที่จะเรียกใช้หนึ่งครั้งสำหรับการทดสอบแต่ละกลุ่ม

rspec_helper.rb:

RSpec.configure do |config|
  ...
  config.before(:suite) do
    Rails.application.load_seed
  end
  ...
end
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.