Po znaczącym rozwiązywaniu problemów stwierdziłem, że muszę uruchomić rake spec
raz (mogę przerwać za pomocą control-c), zanim będę mógł bezpośrednio uruchomić rspec (np. Na podzbiorze naszych specyfikacji). Używamy Rails 3.0.7 i RSpec 2.5.0.
Najwyraźniej rake uruchamia kilka ważnych zadań / kodu konfiguracji bazy danych (mamy własny kod w pliku Rakefile na poziomie głównym i prawdopodobnie w innych miejscach).
Jak mogę uruchomić zadania / kod konfiguracji bazy danych testu rake bez uruchamiania rake spec
?
Oprócz możliwości uruchamiania rspec na podzbiorze plików, używam specjour do rozprzestrzeniania naszych specyfikacji na wiele rdzeni (nie udało mi się jeszcze rozpowszechnić ich w sieci LAN), ale widzę to samo zachowanie, co przy uruchamianiu rspec bezpośrednio: muszę uruchomić rake spec
na każdej testowej bazie danych (zakładając dwa rdzenie) przed specjour działa:
rake spec TEST_ENV_NUMBER=1
control-c (after tests start)
rake spec TEST_ENV_NUMBER=2
control-c (after tests start)
specjour
Uwaga: mój plik config / database.yml ma ten wpis do testu (jak to jest typowe dla równoległych klejnotów testowych):
test:
adapter: postgresql
encoding: unicode
database: test<%=ENV['TEST_ENV_NUMBER']%>
username: user
password:
Paralel_tests wydaje się poprawnie konfigurować swoje bazy danych, ale wiele z naszych specyfikacji zawodzi.
Powinienem również wspomnieć, że uruchomienie specjour prepare
powoduje, że Postgres rejestruje błędy, że nie może znaleźć baz danych, ale je tworzy (bez tabel). Przy kolejnym uruchomieniu nie są rejestrowane żadne błędy, ale także nie są tworzone żadne tabele. Możliwe, że cały mój problem jest po prostu błędem prepare
, więc zgłosiłem to na githubie.
Myślę, że mogę uruchomić dowolny kod na każdej specjour testowej bazie danych, ustawiając Specjour::Configuration.prepare
w .specjour / hooks.rb, więc jeśli są jakieś zadania rake'u lub inny kod, który muszę uruchomić, może tam działać.
Poleciłbym porzucić swoją testową bazę danych, a następnie utworzyć ją ponownie i przeprowadzić migrację:
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
Po tych krokach możesz uruchomić swoje specyfikacje:
gerry3 zauważył, że:
Jednakże, jeśli używasz PostgreSQL, to nie zadziała, ponieważ środowisko rails jest ładowane, co otwiera połączenie z bazą danych. Powoduje
prepare
to niepowodzenie wywołania, ponieważ DB nie może zostać usunięty. Podstępna rzecz.źródło
rake db:test:prepare
.rake db:test:prepare
z uruchomieniem Postgres. Musisz widzieć swój problem z innego powodu.RAILS_ENV=test bundle exec rake db:drop db:create db:schema:load
rake db:test:prepare
to, że jest przestarzały w Railsach 4.bundle exec rake db:drop db:create db:schema:load RAILS_ENV=test
Wszystkie dostarczone rozwiązania wymagają załadowania środowiska Rails, które w większości przypadków nie jest pożądane ze względu na bardzo duże obciążenie i bardzo małą prędkość.
DatabaseCleaner
Klejnot jest również dość powolny i dodaje kolejną zależność do Twojej aplikacji.Po miesiącach zmartwień i irytacji z powodów vide powyżej, w końcu znalazłem następujące rozwiązanie, które jest dokładnie tym, czego potrzebuję. Jest ładny, prosty i szybki. W
spec_helper.rb
:config.after :all do ActiveRecord::Base.subclasses.each(&:delete_all) end
Najlepsze w tym jest to, że: wyczyści tylko te tabele, które skutecznie dotknąłeś (nietknięte modele nie zostaną załadowane, a zatem nie pojawią się w
subclasses
, a także powód, dla którego to nie działa przed testami). Ponadto jest wykonywany po testach, więc (miejmy nadzieję) zielone kropki pojawią się od razu.Jedynym minusem jest to, że jeśli masz brudną bazę danych przed uruchomieniem testów, nie zostanie ona wyczyszczona. Ale wątpię, czy jest to poważny problem, ponieważ testowa baza danych zwykle nie jest dotykana przez testy zewnętrzne.
Edytować
Widząc, że ta odpowiedź zyskała pewną popularność, chciałem ją zmienić, aby była kompletna: jeśli chcesz wyczyścić wszystkie tabele, nawet te nietknięte, powinieneś być w stanie zrobić coś w rodzaju „hacków” poniżej.
Hack 1 - wstępne ładowanie wszystkich modeli dla
subclasses
metodyOceń to przed telefonem
subclasses
:Dir[Rails.root.join("app", "models", "**", "*.rb")].each(&method(:require))
Pamiętaj, że ta metoda może zająć trochę czasu!
Hack 2 - ręczne obcinanie tabel
ActiveRecord::Base.connection.tables.keep_if{ |x| x != 'schema_migrations' }
dostaniesz wszystkie nazwy tabel, z tymi, które możesz zrobić na przykład:
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
źródło
Wygląda na to, że w Railsach 4.1+ najlepszym rozwiązaniem jest po prostu dodanie
ActiveRecord::Migration.maintain_test_schema!
rails_helper porequire 'rspec/rails'
.tzn. nie musisz się już martwić o przygotowywanie bazy danych.
https://relishapp.com/rspec/rspec-rails/docs/upgrade#pending-migration-checks
źródło
W wiosennej aplikacji Rails 4 plik my
bin/setup
jest zwykle rozszerzany o zawartośćputs "\n== Preparing test database ==" system "RAILS_ENV=test bin/rake db:setup"
Jest to bardzo podobne do odpowiedzi Lewiatana , plus wysiew testowego DB, jak
Jak wspomniano w komentarzu, jeśli chcemy najpierw usunąć DB,
rake db:reset
zrób to.Uważam również, że zapewnia to więcej informacji zwrotnych w porównaniu z
rake db:test:prepare
.źródło
Zacząłem od upuszczenia mojej testowej bazy danych
rake db:drop RAILS_ENV=test
podczas próby utworzenia nowej testowej bazy danych napotkałem problem, ponieważ moje konto użytkownika różniło się od konta będącego właścicielem baz danych, więc zamiast tego utworzyłem bazę danych w PostgreSQL.
wpisz
psql
wiersz polecenia, a następnie wykonaj poniższe czynności, aby utworzyć testową bazę danych korzystającą z konta innego niż Twoje.CREATE DATABASE your_database_name OWNER your_db_owner;
następnie uruchom migracje w środowisku testowym.
rake db:migrate RAILS_ENV=test
źródło