Bird
Raised Fist0
Ruby on Railsframework~10 mins

Fixture and factory usage in Ruby on Rails - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Fixture and factory usage
Start Test Setup
↓
Load Fixture Data
↓
Use Fixture in Test
↓
Run Test Assertions
↓
End Test
↓
Start Test Setup
↓
Call Factory to Build Object
↓
Use Factory Object in Test
↓
Run Test Assertions
↓
End Test
Tests start by either loading fixture data or calling a factory to create objects, then use these objects in tests before running assertions and ending.
Execution Sample
Ruby on Rails
test "user has valid email" do
  user = users(:one) # fixture
  assert user.email.include?('@')
end
This test uses a fixture named :one to get a user and checks if the email contains '@'.
Execution Table
StepActionData Loaded/CreatedTest VariableAssertion Result
1Load fixture users(:one)User fixture data with email 'user@example.com'user = users(:one)N/A
2Check if user.email includes '@'N/Auser.email = 'user@example.com'True
3Assert conditionN/Auser.email.include?('@')Pass
4Test endsN/AN/ATest Passed
💡 Test ends after assertion passes
Variable Tracker
VariableStartAfter Step 1After Step 2Final
usernilUser object from fixture with email 'user@example.com'SameSame
Key Moments - 2 Insights
Why do we use fixtures instead of creating objects manually in tests?
Fixtures provide predefined data loaded before tests run, so tests can use consistent data without setup code, as shown in step 1 of the execution_table.
How is a factory different from a fixture in tests?
A factory creates objects dynamically during the test run, unlike fixtures which load static data before tests, allowing more flexible and customized test data.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the value of 'user.email' after step 2?
A'user@example.com'
B'test@domain.com'
Cnil
D'noemail'
💡 Hint
Check the 'Test Variable' column at step 2 in the execution_table.
At which step does the test check if the email contains '@'?
AStep 1
BStep 2
CStep 3
DStep 4
💡 Hint
Look at the 'Action' column in the execution_table for the condition check.
If we replaced the fixture with a factory that creates a user with email 'factory@user.com', what changes in the variable_tracker?
AThe 'user' variable would be nil throughout
BThe 'user' variable would have email 'user@example.com' after step 1
CThe 'user' variable would have email 'factory@user.com' after step 1
DNo change in 'user' variable
💡 Hint
Consider how factories create objects dynamically compared to fixtures.
Concept Snapshot
Fixtures load static test data before tests run.
Factories create test objects dynamically during tests.
Use fixtures for simple, consistent data.
Use factories for flexible, customized data.
In tests, access fixtures by name (e.g., users(:one)).
Factories are called as methods to build objects.
Full Transcript
In Rails testing, fixtures and factories help create test data. Fixtures are predefined data loaded before tests, accessible by names like users(:one). Factories build objects dynamically during tests, allowing more customization. Tests use these objects to check behavior, like verifying a user's email contains '@'. The execution flow starts with loading or creating data, then running assertions, and finally ending the test. Understanding when and how data is prepared helps write clear and reliable tests.

Practice

(1/5)
1. What is the main difference between fixtures and factories in Rails testing?
easy
A. Fixtures use static YAML files, while factories generate data dynamically with Ruby code.
B. Fixtures are faster to write than factories.
C. Factories require no setup, but fixtures need database cleaning.
D. Factories store data in YAML files, fixtures use Ruby code.

Solution

  1. Step 1: Understand fixtures data source

    Fixtures load test data from static YAML files before tests run.
  2. Step 2: Understand factories data generation

    Factories create test data dynamically using Ruby code during test execution.
  3. Final Answer:

    Fixtures use static YAML files, while factories generate data dynamically with Ruby code. -> Option A
  4. Quick Check:

    Fixtures = YAML, Factories = Ruby code [OK]
Hint: Fixtures = YAML files, factories = Ruby code [OK]
Common Mistakes:
  • Confusing fixtures as dynamic data generators
  • Thinking factories use YAML files
  • Assuming fixtures are created with Ruby code
2. Which of the following is the correct syntax to define a factory for a User model using FactoryBot?
easy
A. factory :user do name { "Alice" } end
B. define_factory :user do name "Alice" end
C. FactoryBot.define do factory :user do name { "Alice" } end end
D. factory :user { name: "Alice" }

Solution

  1. Step 1: Recognize FactoryBot syntax

    FactoryBot factories are defined inside a block passed to FactoryBot.define.
  2. Step 2: Check block and attribute syntax

    Attributes use curly braces with Ruby code, e.g., name { "Alice" }.
  3. Final Answer:

    FactoryBot.define do factory :user do name { "Alice" } end end -> Option C
  4. Quick Check:

    FactoryBot.define + block + attribute with braces [OK]
Hint: FactoryBot.define block wraps factory definitions [OK]
Common Mistakes:
  • Omitting FactoryBot.define block
  • Using wrong attribute syntax without braces
  • Using invalid factory syntax like curly braces for block
3. Given the following factory and test code, what will user.name output?
FactoryBot.define do
  factory :user do
    name { "Bob" }
  end
end

user = FactoryBot.create(:user)
medium
A. "Alice"
B. nil
C. Raises an error because name is missing
D. "Bob"

Solution

  1. Step 1: Understand factory attribute assignment

    The factory sets the name attribute to "Bob" using a block.
  2. Step 2: FactoryBot.create builds and saves user

    Calling create(:user) builds a user with name "Bob" and saves it.
  3. Final Answer:

    "Bob" -> Option D
  4. Quick Check:

    Factory attribute value = "Bob" [OK]
Hint: Factory attribute blocks set values directly [OK]
Common Mistakes:
  • Assuming default name is nil
  • Confusing create with build (create saves)
  • Expecting name to be "Alice" without definition
4. You have a fixture file users.yml with a user named john. In your test, you write users(:john) but get an error. What is a likely cause?
medium
A. The test database is not migrated.
B. The fixture file is not loaded or declared in the test setup.
C. You must use FactoryBot.create instead of fixtures.
D. The user named john is misspelled in the fixture file.

Solution

  1. Step 1: Check fixture loading in test

    Fixtures must be declared or loaded for the test to access them.
  2. Step 2: Confirm fixture file presence and naming

    If the fixture file exists but is not loaded, users(:john) will raise an error.
  3. Final Answer:

    The fixture file is not loaded or declared in the test setup. -> Option B
  4. Quick Check:

    Fixtures must be loaded to use named references [OK]
Hint: Load fixtures before using named references [OK]
Common Mistakes:
  • Assuming misspelling without checking loading
  • Thinking FactoryBot is required instead of fixtures
  • Ignoring fixture loading setup in test
5. You want to create multiple users with different emails using factories in a test. Which approach correctly creates 3 users with unique emails?
hard
A. factory :user do sequence(:email) { |n| "user#{n}@example.com" } end users = 3.times.map { FactoryBot.create(:user) }
B. factory :user do email "user@example.com" end users = 3.times.map { FactoryBot.create(:user) }
C. factory :user do email { "user@example.com" } end users = FactoryBot.create_list(:user, 3)
D. factory :user do email { "user@example.com" } end users = FactoryBot.build(:user, 3)

Solution

  1. Step 1: Understand sequence usage in factories

    Using sequence(:email) generates unique emails for each created user.
  2. Step 2: Confirm multiple user creation with unique emails

    Calling FactoryBot.create inside a loop with sequence ensures 3 users with different emails.
  3. Final Answer:

    factory :user do sequence(:email) { |n| "user#{n}@example.com" } end users = 3.times.map { FactoryBot.create(:user) } -> Option A
  4. Quick Check:

    Sequence + create loop = unique users [OK]
Hint: Use sequence for unique attributes in factories [OK]
Common Mistakes:
  • Using static email causing duplicates
  • Using build instead of create (no DB save)
  • Not using sequence for unique values
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard