I’m still using fixtures. Shame, I know.
Why I do use them instead of Factory Girl or other solution like that? Well, fixtures can be much more closer to real data than mocks from Factory. How come, You ask? Fixtures are imaginary data exactly like mocks from other sources!
My answer is: that depends how You create fixtures. If You create them by hand, indeed they are disconnected from real world (like all mocks).
But I prefer to extract fixtures from real (production) database. That way I can easily pick entries created by users which are edge cases. The only trouble is with creating fixtures. For some time I’m using modified extract_fixtures rake task. I have added some conditions to extracting process – SQL condition to select only particular records and adjusted syntax to recent rake.
This is useful especially when You are about to take over application code which has no tests. Extracting real data is quick way to start write integration tests (in such case they have are most efficient – time invested and application code coverage).
How to extract fixtures without pain?
Now I want to share with You next improvement to this recipe. Old fixtures can be left unchanged (as long You don’t use ERb to spice them up).
Rake task load old fixtures file and add new records as selected from database by arguments You are providing. More – it keeps old fixtures names so all Your tests using
some_table :fixture will work (but don’t You dare to create attribute called
fixtures_old_key_value :)) ). As a bonus attributes in Your fixture file will be sorted by attribute name!
OK some examples (written by hand not real YML files I hope there are no mistakes ;)) :
cat test/fixtures/entries.yml one: attr1: value attr2: value created_at: 2009-09-10 11:22 rake extract_fixtures[entries,1,"created_at<'2009-09-01'"] cat test/fixtures/entries.yml one: attr1: value attr2: value created_at: 2009-09-10 11:22 id: 1 entries_2: attr1: value from DB attr2: Also value from DB created_at: 2009-08-01 22:11 id: 2
All is clear? In file there was fixture named
:one, after rake task we have added new one selected from database, new fixture has name TABLE_NAME_ID, old fixture has unchanged name.
You can add DISCARD=true and old fixtures will be well... discarded :)
Rake task take following arguments:
- table name
- limit number of records extracted from database
- WHERE condition
Rake has one limitation - it treats all commas as arguments separators, so it is not possible to use IN operator. Instead of
rake extract_fixtures[entries,10,"id IN (1,2,3)"] write
rake extract_fixtures[entries,10,"id=1 OR id=2 OR id=3)"].
You can download rake task file: http://nhw.pl/download/extract_fixtures.rake