-->

RSpec & Database Cleaner - Keep certain objects pe

2019-02-25 19:03发布

问题:

I have (belatedly) started testing my Rails app (a shopping website) with RSpec/capybara, using database cleaner to clear the database and Factory Girl to generate new objects for every test (like most people do). This works fine, and I do think it is a good idea to clear the data between tests.

However, it can get slow and (as far as I can figure out) a bit tedious to generate multiple instances of the same object. There are some objects that are always the same in my database, or that I will always generate an identical copy of for testing. For example, my Package model, which defines the pricing and feature limits for a subscription package. It will probably never change.

Is there a way, with this configuration (please comment and specify if you require more info), to put certain instances of objects in the test database and exclude them from Database Cleaner, or any other way to keep permanent copies of specific objects in your test database?

This is mainly to increase testing speed.

回答1:

If you have database objects that your application never changes, and that are the same in your production and development databases as well as in your test databases, the right thing to do is to make them seeds. Create them in db/seeds.rb. More on seeds here: http://guides.rubyonrails.org/active_record_migrations.html#migrations-and-seed-data

If the objects that you're talking about only belong in your test database, you could make them Rails fixtures. More on fixtures here: http://guides.rubyonrails.org/testing.html#the-low-down-on-fixtures (Beware, though, that fixtures are usually a bad idea, because they make your tests harder to read and encourage you to write tests around existing fixtures, which leads to an entangled mess. Test clarity and robustness is more important than speed.)

If you're using Database Cleaner's truncation or deletion strategy (probably because you're using a Javascript-capable driver with Capybara), and you've used either of the foregoing methods to leave data in your test database between tests, you can tell Database Cleaner to not empty specific tables:

DatabaseCleaner.strategy = :truncation, {:only => %w[widgets dogs some_other_table]}

or

DatabaseCleaner.strategy = :truncation, {:except => %w[widgets]}

(Source: https://github.com/bmabey/database_cleaner#how-to-use) I don't know of a way to tell Database Cleaner to delete some instances of a given class and not others, however.