Все представленные решения требуют загрузки среды Rails, которая в большинстве случаев не соответствует желаемому поведению из-за очень больших издержек и очень низкой скорости. DatabaseCleaner
gem также довольно медленный и добавляет еще одну зависимость в ваше приложение.
После нескольких месяцев огорчения и досады из-за причин, приведенных выше, я наконец нашел следующее решение как раз то, что мне нужно. Это красиво, просто и быстро. В spec_helper.rb
:
config.after :all do
ActiveRecord::Base.subclasses.each(&:delete_all)
end
Самое приятное в этом: это очистит только те таблицы, которые вы эффективно коснулись (нетронутые модели не будут загружены и, следовательно, не появятся в subclasses
, также причина, по которой это не так) t до испытаний). Кроме того, он выполняется после тестов, поэтому (надеюсь) зеленые точки появятся сразу.
Единственным недостатком этого является то, что если у вас есть грязная база данных до запуска тестов, она не будет очищена. Но я сомневаюсь, что это серьезная проблема, поскольку тестовая база данных обычно не затрагивается сторонними тестами.
Редактировать
Поскольку этот ответ приобрел некоторую популярность, я хотел отредактировать его для полноты: если вы хотите очистить все таблицы, даже те, которые не были затронуты, вы сможете сделать что-то вроде " хаки "ниже.
Hack 1 - предварительная загрузка всех моделей для subclasses
метода
Оцените это перед звонком subclasses
:
Dir[Rails.root.join("app", "models", "**", "*.rb")].each(&method(:require))
Обратите внимание, что этот метод может занять некоторое время!
Hack 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