Create test fixtures

Test fixtures provide test data to be used by our automated tests.

Inspect the model classes

We must be familiar with the LimerIQ app’s model classes before we proceed with writing controller tests for the app. The following class diagram depicts the design of the app’s two model classes, Limerick and User.

Inspect the code for the Limerick and User model classes by opening the files app/models/limerick.rb and app/models/user.rb, respectively, in VS Code.

Note that app’s model classes are as depicted in the class diagram. Limerick has two attributes (title and limerick_text), and User was generated by Devise. Additionally, there is a one-to-many association between User and Limerick (a user has many limericks, and a limerick belongs to one user).

Inspect the generated fixtures

When a model class is generated with the rails generate model command (or via Devise), test fixtures for the model class are also generated in the test/fixtures folder.

The LimerIQ app has two model classes, Limerick and User. The generated fixtures in these model classes can be found in test/fixtures/limericks.yml and test/fixtures/users.yml, respectively.

Note that the fixture files have names that are snake_case and pluralized versions of the model class names. Note also that the fixtures are in written in the YAML language.

Open the limericks.yml fixtures file in VS Code. You should see entries like this:

one:
  title: MyString
  limerick_text: MyText

two:
  title: MyString
  limerick_text: MyText

Note that there are two Limerick objects specified here. One is named one and the other is named two. We will use these names to retrieve fixture objects later when we write our controller tests. Each object has its title and limerick_text attributes set to the generated placeholder values MyString and MyText, respectively. We will replace these placeholders with more realistic values in a moment.

Open the users.yml fixtures file in VS Code. You should see entries like this (comments elided):

one: {}

two: {}

Note that these two User objects have no attribute values specified, as indicated by the empty braces {}. We will add attribute values to these fixtures in a moment.

Note that it is a common practice to name each fixture of a given type one, two, etc.; however, following this naming convention is not strictly required.

Note that it is also common to have two fixtures of each type; however, more fixtures can be added if needed by our tests.

Add realistic data to the fixtures

Update the User fixtures by adding an email attribute with a realistic value to each user. For user fixtures, it is unnecessary to add any other attributes (such as password).

one:
  email: alice@email.com

two:
  email: bob@email.com

Note that we deleted the empty braces {}, which denote that a fixture has no attributes.

Update the Limerick fixtures’ title and limerick_text attribute values to be more realistic by editing them in VS Code as in the code below.

Additionally, recall that there is a has_many/belongs_to association between the User and Limerick classes. Because the belongs_to declaration includes an implicit validation that an associated object is present, we must add to each of our Limerick fixtures an association link to a User fixture. To accomplish this, we must add an additional association-link attribute to each Limerick fixture. To determine the name of the association-link attribute to add, inspect the belongs_to declaration in the Limerick class, and note that :author is the name specified for the associated User object. Thus, we add an author attribute to each of our Limerick fixtures as follows.

one:
  title: There once was a farmer from Leeds
  limerick_text: "There once was a farmer from Leeds,\nWho swallowed a packet of seeds.\nIt soon came to pass,\nHe was covered with grass,\nBut has all the tomatoes he needs."
  author: one

two:
  title: A canner, exceedingly canny
  limerick_text: "A canner, exceedingly canny\nOne morning remarked to his granny,\n\"A canner can can\nAnything that he can;\nBut a canner can't can a can, can he?\""
  author: one

Note that because the limerick_text string values contain special escape sequences (\n to print a newline and \" to print a quotation mark), those strings must be surrounded in quotation marks ("). In contrast, the title string values do not contain escape sequences and therefore need not be surrounded in quotation marks.

Note that each fixture now has an author attribute, and each such attribute is set to one. The name one in this case refers to the User fixture named one from the users.yml fixture file. That means that each of the Limerick feature objects belongs to the same User fixture object (one). Note that the User fixture object two has no Limerick objects in these fixtures.

Test the fixtures for bugs

When we wrote our fixture code, we may have accidentally introduced bugs, such as syntax and validation errors, into that code. If we run at least one test, Rails will load and run our fixture code, revealing any such bugs. However, initially, we have no tests defined, so we will add one as follows.

Open the controller test file test/controllers/limericks_controller_test.rb in VS Code. The file should look like this:

require "test_helper"

class LimericksControllerTest < ActionDispatch::IntegrationTest
  # test "the truth" do
  #   assert true
  # end
end

Note that the LimericksControllerTest class contains one test case named "the truth" that is commented out.

Uncomment the test case as follows.

require "test_helper"

class LimericksControllerTest < ActionDispatch::IntegrationTest
  test "the truth" do
    assert true
  end
end

Note that the controller-test class now contains a very basic test case. Although the test case essentially does nothing except report that the test passed, its presence will cause Rails to load and run our test fixtures, which is our main goal at this point.

Run the test case (and our test fixture code) using the following command.

rails test -v

Note that this command runs all of the test cases defined in the test folder (one in our case) and should produce output that looks like the following. The -v option in the command is for verbose (long) output.

Running 1 tests in a single process (parallelization threshold is 50)
Run options: -v --seed 62212

# Running:

LimericksControllerTest#test_the_truth = 0.13 s = .

Finished in 0.133011s, 7.5182 runs/s, 7.5182 assertions/s.
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips

Note that the above output indicates that our test (LimericksControllerTest#test_the_truth) was run, and no error messages are displayed. If the command produced error messages, they would likely indicate that there are bugs in our fixture code that we must fix.


⏴ Back Next ⏵