Backend Pattern Test - department-of-veterans-affairs/caseflow GitHub Wiki

[Pattern] Test

Description

Caseflow includes three kinds of tests that are subdivided into folders.

Location

  • spec/

Best Practices

High-Level

Ordering in Tests

It is not guaranteed that the order in which you create factories will be the same order in the result.

Examples:

  • Testing that a DB query sorts results by created_at or some other timestamp. Don't assume that if you create 2 factories in the test, the first one will always come first. Instead, specify a specific timestamp for each factory to ensure the test will be idempotent.

  • Testing that the JSON rendered by the controller has certain attributes for some of the entries. Don't assume that if you create multiple factories, the JSON will return them in the same order. Instead of doing something like this:

    create(:hearing)
    create(:hearing)
    hearings = JSON.parse(response.body)["hearings"]
    expect(hearings[0]["judge_last_name"]).to eq "Smith"

    do this instead:

    first_hearing = create(:hearing)
    hearings = JSON.parse(response.body)["hearings"]
    first_hearing_result = hearings.find { |hash| hash["id"] == first_hearing.id }
    expect(first_hearing_result["judge_last_name"]).to eq "Smith"

Use aggregate_failures metadata

Setup for tests occupies a significant amount of time in Caseflow. If you have a group of tests for a particular subject, you can use aggregate_failures to avoid the cost of redundant setup time: 2

This:

it { expect(subject.status).to eq 200 }
it { expect(JSON.parse(subject.body)["veteran"]["email_address"]).to eq "[email protected]" }
it { expect(JSON.parse(subject.body)["veteran"]["full_name"]).to eq "Test User" }

can become:

it "returns expected response", :aggregate_failures do
  expect(subject.status).to eq 200
  expect(JSON.parse(subject.body)["veteran"]["email_address"]).to eq "[email protected]"
  expect(JSON.parse(subject.body)["veteran"]["full_name"]).to eq "Test User"
end

The test-prof gem also has a RuboCop that can automatically apply this pattern to some of our tests. You can enable this in your development environment by modifying the .rubocop.yml file as described. Unfortunately, this can't be enabled in Code Climate because they do not allow installing of gems.

Resources

Additional Reading

⚠️ **GitHub.com Fallback** ⚠️