If you have to write an integration test that includes a specific date or time, there's an extra step you need to take to ensure that your tests don't break when the date/time changes. Take the following example for instance:
Scenario (cash_discounts_list.feature
):
Scenario: List the cash discounts sorted by status, type, end date
Given there are some cash discounts
When I list the "cash_discounts"
Then I should see the following table
| Type | End Date | Percentage | Status |
| Energy | 10/15/2014 | 1.0% | Active |
| Fertilizer | 10/16/2014 | 8.0% | Active |
| Fertilizer | 10/19/2014 | 2.0% | Active |
| Seed | 10/22/2014 | 7.0% | Inactive |
Step Definition:
Given(/^there are some cash discounts$/) do
create_order_types
FactoryGirl.create(:cash_discount, end_date: Date.today, percent_discount: 8, order_type: OrderType.find_by_name("Fertilizer"), active: true)
FactoryGirl.create(:cash_discount, end_date: Date.today + 3.days, percent_discount: 2, order_type: OrderType.find_by_name("Fertilizer"), active: true)
FactoryGirl.create(:cash_discount, end_date: Date.today + 6.days, percent_discount: 7, order_type: OrderType.find_by_name("Seed"), active: false)
FactoryGirl.create(:cash_discount, end_date: Date.today - 1.days, percent_discount: 1, order_type: OrderType.find_by_name("Energy"), active: true)
end
If you were to run script/ci
on 10/16/2014, these would pass. If you were to run them on 10/17/2014, these would fail. Why? Because Date.today
no longer returns 10/16/2014. Using the timecop gem, we can "freeze time to a specific point" when we need to run a time-specific test. If you look at generic_steps.rb
, you'll see that there's a step defined to make adding this to a scenario pretty trivial:
Given(/^the date and time is "(.*?)"$/) do |time|
Chronic.time_class = Time.zone
Timecop.freeze(Chronic.parse(time))
end
To make the test pass (no matter which date we run it on), we can update it like so:
Scenario: List the cash discounts sorted by status, type, end date
Given the date and time is "10/16/2014 10:00 AM"
And there are some cash discounts
When I list the "cash_discounts"
Then I should see the following table
| Type | End Date | Percentage | Status |
| Energy | 10/15/2014 | 1.0% | Active |
| Fertilizer | 10/16/2014 | 8.0% | Active |
| Fertilizer | 10/19/2014 | 2.0% | Active |
| Seed | 10/22/2014 | 7.0% | Inactive |
By default, once you use timecop
to freeze the time, it remains that way. You can unfreeze timecop
by using Timecop.return
. To avoid having to include this in every single scenario, we've included it in features/support/env.rb
in the After
block so that it runs after each of the scenarios.