रेक स्पेक चलाने के बिना रेल rspec परीक्षणों के लिए मैं परीक्षण डेटाबेस कैसे तैयार करूं?


83

महत्वपूर्ण समस्या निवारण के बाद, मुझे लगा कि मुझे rake specएक बार दौड़ने की आवश्यकता है (मैं नियंत्रण-सी के साथ गर्भपात कर सकता हूं) इससे पहले कि मैं सीधे आरएसपीसी चला सकता हूं (जैसे कि हमारे चश्मे का सबसेट)। हम रेल 3.0.7 और RSpec 2.5.0 चला रहे हैं।

स्पष्ट रूप से, रेक कुछ महत्वपूर्ण डेटाबेस सेटअप कार्य / कोड चला रहा है (हमारे पास रूट कोड रेलेक राफाइल और संभवतः अन्य स्थानों पर कस्टम कोड है)।

बिना रन के मैं रेक टेस्ट डेटाबेस सेटअप कार्य / कोड कैसे चला सकता हूं rake spec?

फ़ाइलों के एक सबसेट पर rspec चलाने में सक्षम होने के अलावा, मैं कई कोर में हमारे चश्मे को फैलाने के लिए specjour का उपयोग कर रहा हूं (अभी तक LAN में उन्हें फैलाने के साथ सफलता नहीं मिली है), लेकिन मुझे recec चलाने के लिए उसी तरह का व्यवहार दिखाई देता है सीधे: मैं rake specप्रत्येक परीक्षण डेटाबेस (दो कोर को संभालने) पर चलने से पहले कार्य करना चाहता हूं:

rake spec TEST_ENV_NUMBER=1
control-c (after tests start)
rake spec TEST_ENV_NUMBER=2
control-c (after tests start)
specjour

नोट: मेरे कॉन्‍फ़िगर / database.yml में परीक्षण के लिए यह प्रविष्टि है (जैसा कि समानांतर परीक्षण रत्नों के लिए आम है):

test:
  adapter: postgresql
  encoding: unicode
  database: test<%=ENV['TEST_ENV_NUMBER']%>
  username: user
  password:

समानांतर_टैस्ट अपने डेटाबेस को सही ढंग से सेट करने के लिए लगता है, लेकिन हमारे कई चश्मे विफल हो जाते हैं।

मुझे यह भी उल्लेख करना चाहिए कि रनिंग specjour prepareकारणों को लॉग त्रुटियों को स्थगित करता है जो इसे डेटाबेस नहीं मिल सकता है, लेकिन यह उन्हें (टेबल के बिना) बनाता है। बाद में चलने पर, कोई त्रुटि लॉग नहीं होती है, लेकिन कोई तालिका भी नहीं बनाई जाती है। यह संभव है कि मेरा पूरा मुद्दा बस एक बग में है prepare, इसलिए मैंने इसे गीथूब पर रिपोर्ट किया।

मुझे लगता है कि मैं Specjour::Configuration.prepare.specjour / hooks.rb में सेटिंग करके प्रत्येक सट्टेबाजी परीक्षण डेटाबेस पर मनमाना कोड चला सकता हूं, इसलिए यदि कोई रेक कार्य या अन्य कोड जिसे मुझे चलाने की आवश्यकता है, तो यह वहां काम कर सकता है।

जवाबों:


14

मुझे काम पर CI सिस्टम सेट करने में एक समान समस्या थी, इसलिए मैंने धीरे-धीरे इसे संभालने के लिए एक सिस्टम तैयार किया। यह सबसे अच्छा समाधान नहीं हो सकता है, लेकिन यह मेरी स्थिति में मेरे लिए काम करता है और मैं हमेशा चीजों को करने के बेहतर तरीकों की तलाश में हूं।

मेरे पास एक परीक्षण डेटाबेस है जिसे मुझे सेटअप की आवश्यकता थी, लेकिन काम करने के लिए हमारे परीक्षणों के लिए लोड किए गए डेटा की भी आवश्यकता थी।

हेकिंग के तहत क्या हो रहा है, यह देखने के लिए --trace विकल्प के साथ रेक कार्यों के निवारण की मूल बातें है। जब मैंने ऐसा किया, तो मैंने पाया कि रेक स्पेक चलाने से कई चीजें हुईं जिन्हें मैं कस्टम रेक कार्य में दोहरा सकता था (या जैसा कि मैंने फिट देखा था) संशोधित कर सकता था।

यहाँ एक उदाहरण है कि हम क्या करते हैं।

desc "Setup test database - drops, loads schema, migrates and seeds the test db"
task :test_db_setup => [:pre_reqs] do
  Rails.env = ENV['RAILS_ENV'] = 'test'
  Rake::Task['db:drop'].invoke
  Rake::Task['db:create'].invoke
  result = capture_stdout { Rake::Task['db:schema:load'].invoke }
  File.open(File.join(ENV['CC_BUILD_ARTIFACTS'] || 'log', 'schema-load.log'), 'w') { |f| f.write(result) }
  Rake::Task['db:seed:load'].invoke
  ActiveRecord::Base.establish_connection
  Rake::Task['db:migrate'].invoke
end

यह केवल एक उदाहरण है, और हमारी स्थिति के लिए विशिष्ट है, इसलिए आपको यह पता लगाने की आवश्यकता होगी कि आपके परीक्षण db सेटअप को प्राप्त करने के लिए क्या करने की आवश्यकता है, लेकिन रेक के --trace विकल्प का उपयोग करके यह निर्धारित करना काफी आसान है।

इसके अतिरिक्त, यदि आप पाते हैं कि परीक्षण सेटअप बहुत लंबा हो रहा है (जैसा कि हमारे मामले में है), तो आप डेटाबेस को .sql प्रारूप में भी डंप कर सकते हैं और परीक्षण डेटाबेस पाइप को सीधे लोड करने के लिए mysql में रख सकते हैं। हम उस तरह से परीक्षण db सेटअप से कई मिनट बचाते हैं। मैं इसे यहां नहीं दिखाता क्योंकि यह चीजों को काफी हद तक जटिल कर देता है - इसे बासी होने आदि के बिना ठीक से उत्पन्न करने की आवश्यकता है।

HTH


हां, मैंने --ट्रेस के साथ रेक स्पेक चलाया है और इसके कुछ कामों को मेरे तैयार किए गए अटकल हुक में दोहराने का प्रयास किया है, लेकिन यह अभी तक काम नहीं किया है। मैं संभवतः चीजों को स्थापित करने के लिए एक पूरी तरह से अलग रेक कार्य लिख सकता था, लेकिन यह एक और कदम है जिससे मैं बचने की उम्मीद कर रहा था।
gerry3

170

मैं आपके परीक्षण डेटाबेस को छोड़ने की सिफारिश करूंगा, फिर इसे फिर से बनाऊंगा और माइग्रेट करूंगा:

bundle exec rake db:drop RAILS_ENV=test
bundle exec rake db:create RAILS_ENV=test
bundle exec rake db:schema:load RAILS_ENV=test

इन चरणों के बाद आप अपना चश्मा चला सकते हैं:

bundle exec rspec spec

gerry3 ने कहा कि:

एक सरल समाधान बस चलाना है rake db:test:prepare

हालाँकि, यदि आप PostgreSQL का उपयोग कर रहे हैं तो यह काम नहीं करेगा क्योंकि रेल का वातावरण लोड हो जाता है, जो एक डेटाबेस कनेक्शन को खोलता है। इसके कारण prepareकॉल विफल हो जाती है, क्योंकि DB को छोड़ा नहीं जा सकता है। मुश्किल बात।


47
एक सरल समाधान बस चलाना है rake db:test:prepare
gerry3

7
मुझे rake db:test:preparePostgres के साथ चलने में कोई समस्या नहीं है । आप किसी अन्य कारण से अपना मुद्दा देख रहे होंगे।
gerry3

अगर db: परीक्षण: तैयार काम नहीं करता है तो आप कुछ टाइपिंग को बचाने के लिए कम से कम कमांड इनलाइन डाल सकते हैं:RAILS_ENV=test bundle exec rake db:drop db:create db:schema:load
funwhilelost

11
ऐसा लगता है कि rake db:test:prepareरेल 4 में पदावनत है
मार्केज़ादा

8
आप इस तरह से रेक कार्य कर सकते हैं:bundle exec rake db:drop db:create db:schema:load RAILS_ENV=test
डेवगसन

14

प्रदान किए गए समाधानों में सभी रेल्स पर्यावरण को लोड करने की आवश्यकता होती है, जो कि ज्यादातर मामलों में, बहुत बड़े ओवरहेड और बहुत कम गति के कारण वांछित व्यवहार नहीं है। DatabaseCleanerमणि भी बल्कि धीमा है, और यह आपके ऐप पर एक और निर्भरता जोड़ता है।

Supra के कारणों के लिए chagrin और vexation धन्यवाद के महीनों के बाद, मैंने आखिरकार निम्नलिखित समाधान खोज लिया है कि मुझे क्या चाहिए। यह अच्छा, सरल और तेज है। इन spec_helper.rb:

config.after :all do
  ActiveRecord::Base.subclasses.each(&:delete_all)
end

इसके बारे में सबसे अच्छा हिस्सा है: यह केवल उन तालिकाओं को स्पष्ट करेगा जिन्हें आपने प्रभावी रूप से छुआ है (अछूता मॉडल लोड नहीं किया जाएगा और इस प्रकार प्रकट नहीं होता है subclasses, यह भी कारण है कि यह परीक्षण से पहले काम नहीं करता है )। इसके अलावा, यह परीक्षणों के बाद निष्पादित होता है, इसलिए (उम्मीद है) हरे रंग के डॉट्स तुरंत दिखाई देंगे।

इसका केवल नकारात्मक पक्ष यह है कि यदि आपके पास परीक्षण चलाने से पहले एक गंदा डेटाबेस है, तो इसे साफ नहीं किया जाएगा। लेकिन मुझे संदेह है कि यह एक प्रमुख मुद्दा है, क्योंकि परीक्षण डेटाबेस आमतौर पर बाहरी परीक्षणों से छुआ नहीं जाता है।

संपादित करें

यह देखते हुए कि इस उत्तर ने कुछ लोकप्रियता हासिल की है, मैं इसे पूर्णता के लिए संपादित करना चाहता था: यदि आप सभी तालिकाओं को साफ़ करना चाहते हैं , यहां तक ​​कि जिन्हें छुआ नहीं गया है, आपको नीचे दिए गए "हैक्स" की तरह कुछ करने में सक्षम होना चाहिए।

हैक 1 - subclassesविधि के लिए सभी मॉडलों को पूर्व-लोड करना

कॉल करने से पहले इसका मूल्यांकन करें subclasses:

Dir[Rails.root.join("app", "models", "**", "*.rb")].each(&method(:require))

ध्यान दें कि इस विधि में कुछ समय लग सकता है!

हैक 2 - मैन्युअल रूप से तालिकाओं को छोटा करना

ActiveRecord::Base.connection.tables.keep_if{ |x| x != 'schema_migrations' }

आपको सभी तालिका नाम मिलेंगे, जिनके साथ आप कुछ ऐसा कर सकते हैं:

case ActiveRecord::Base.configurations[Rails.env]["adapter"]
when /^mysql/, /^postgresql/
  ActiveRecord::Base.connection.execute("TRUNCATE #{table_name}")
when /^sqlite/
  ActiveRecord::Base.connection.execute("DELETE FROM #{table_name}")
  ActiveRecord::Base.connection.execute("DELETE FROM sqlite_sequence where name='#{table_name}'")
end

साफ! यह काफी उपयोगी है।
अपवित्रता

7

ऐसा प्रतीत होता है कि रेल 4.1+ में, सबसे अच्छा उपाय यह है कि ActiveRecord::Migration.maintain_test_schema!आप अपने रेल्स_हेल्पर में जोड़ दें require 'rspec/rails'

यानी अब आपको डेटाबेस तैयार करने के लिए परेशान होने की जरूरत नहीं है।

https://relishapp.com/rspec/rspec-rails/docs/upgrade#pending-migration-checks


3

एक स्प्रिंग-इफाइड रेल्स 4 ऐप में, मुझे bin/setupआमतौर पर शामिल करने के लिए संवर्धित किया जाता है

puts "\n== Preparing test database =="
system "RAILS_ENV=test bin/rake db:setup"

यह लेविथान के उत्तर के समान है , साथ ही परीक्षण डीबी को बोना है, जैसा कि

rake db:setup # डेटाबेस बनाएं, स्कीमा लोड करें, और बीज डेटा के साथ आरंभ करें
(
पहले डेटाबेस को भी ड्रॉप करने के लिए उपयोग db:reset करें)

जैसा कि टिप्पणी में उल्लेख किया गया है, यदि हम पहले DB को छोड़ना चाहते हैं, rake db:resetतो बस यही करता है।

मुझे यह भी पता चलता है कि इसकी तुलना में यह अधिक प्रतिक्रिया प्रदान करता है rake db:test:prepare


0

मैंने अपना परीक्षण डेटाबेस गिराना शुरू किया rake db:drop RAILS_ENV=test

जब मैं एक नया परीक्षण डेटाबेस बनाने की कोशिश कर रहा था तो मैं एक समस्या में भाग गया क्योंकि मेरा उपयोगकर्ता खाता डेटाबेस के मालिक के रूप में खाता नहीं था, इसलिए मैंने इसके बजाय PostgreSQL में डेटाबेस बनाया।

psqlकमांड प्रॉम्प्ट में टाइप करें और फिर एक परीक्षण डेटाबेस बनाने के लिए नीचे चलाएं जो आपके स्वयं के अलावा किसी अन्य खाते का उपयोग करता है। CREATE DATABASE your_database_name OWNER your_db_owner;

फिर परीक्षण वातावरण में अपने माइग्रेशन चलाएं। rake db:migrate RAILS_ENV=test

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.