Test Fixtures
What they are
In the world of testing, a fixture is a specific environment in which you can run a test. In the world of Rails, a test fixture is a specification of the initial contents of a model (or models) under test. If, for example, we want to ensure that our beverages table starts off with a known data at the start of every unit test, we can specify those contents in a fixture.
You specify fixture data in the test/fixtures directory. These files contain test data in YAML format. Each fixture file contains the data for a single model. The name of the fixture file is significant: the base name of the file must match the name of a database table. For example, if we need some data for a Beverage model, which is stored in the beverages table, we’ll add it to the file called beverages.yml.
A fixture file might look something like this:
1
2
3
4
5
6
7
8
9
one:
title: MyString
description: MyText
price: 9.99
two:
title: MyString
description: MyText
price: 9.99
The file contains an entry for each row that we want to insert into the database. Each row is given a name. This name has no significance as far as the database is concerned - it isn’t inserted into the row data. Instead the name gives us a convenient way to reference this test data inside our code. The names generated by Rails can be changed, though these names are also used in the generated integration tests as well.
Picking good fixture names
You want to keep the names of fixtures as self-explanatory as possible.
Some examples of good names:
- valid_order_for_fred
- fred
- christmas_order
- invalid_credit_card
- aunt_mary
Some examples of bad names:
- order4
- customer1
- p1
Active Storage fixtures
Fixtures that have images on them are handled a little differently. The image isn’t defined on the fixture with the rest of its attributes like its title. Instead, you leave the image attribute undefined on it and define them in a different file. You define them through “blobs” which point to the image in the file tree (You should have the image you’re defining in test/fixtures/files for this to work) and then attach those blobs to the original fixture through an intermediary attachment.
This will look something like this:
1
2
3
# test/fixtures/beverages.yml
mai_tai:
title: Mai Tai
1
2
3
4
5
# test/fixtures/active_storage/attachments.yml
mai_tai:
record: mai_tai (Beverage)
name: featured_image
blob: blob_mai_tai
1
2
# test/fixtures/active_storage/blobs.yml
blob_mai_tai: <%= ActiveStorage::FixtureSet.blob filename: 'mai_tai.jpg' %>
First you create you initial fixture in the beverages file, then the blob for the image in the blobs file, and finally the attachment to link the two together in the attachments file.
Action Text fixtures
Fixtures that use rich text fields are somewhat similar to how active storage fixtures are handled. Again, you do not define the rich text attributes on the initial fixture. Instead you define them in another file: test/fixtures/action_text/rich_texts.yml.
This will look something like this:
1
2
3
# test/fixtures/beverages.yml
mai_tai:
title: Mai Tai
1
2
3
4
5
#test/fixtures/action_text/rich_texts.yml
mai_tai_ingredient_section:
record: mai_tai (Beverage)
name: ingredient_section
body: <ul><li>1 1/2 ounces white rum</li></ul>
External resources
Ruby on Rails Guides: Testing Rails Applications
Notes
Log 1
Thought
Something I figured out about tests: I’m getting errors when I tried adding the rich_text attributes to my fixtures for beverages. The error says the beverages table doesn’t have any of these rich_text attributes as columns. This makes sense initially to me, active storage attributes like images are also handled differently, through blobs, so maybe I need to treat these rich_text attributes similarly. Will attempt this and come back to update on what happened.
Result
My thought was correct. I did need to handle these in the same manner I handled image fixtures.