Scenario: Scheduling a 90-day Review Given an employee is hired 3/17/2013 When I schedule a review Then the review should be scheduled for 6/17/2013
In this scenario we are hard-coding dates, which will cause us headaches when we go to maintain this code down the road. A more maintainable scenario which uses plain English could read like this:
Scenario: Scheduling a 90-day Review Given an employee is hired "today" When I schedule a review Then the review should be scheduled for "90 days from today"
You may be thinking "What's the big deal? 'Today' (or 'yesterday', or 'tomorrow' for that matter) is easy to parse out, and I bet I could whip together a little helper method to get the right date for "90 days from today" Done and done. Or is it?
Simple rolling dates such as "yesterday" or "tomorrow" may not be too difficult to work with as you can just subtract or add a day to the current date, but what about more complex dates? Complex dates described in natural language such as "five months ago" and "second Tuesday July 2014" pose more of a challenge, and rolling your own date parsing logic is almost never a good idea, not to mention almost certainly out of scope for the problem you're trying to solve.
So given that hard-coding is out the question, rolling your own parser is out of scope, and we want to encourage natural language in our gherkin how do you handle these kind of dates? Enter the Chronic gem.
Chronic
The Chronic gem is a natural language date/time parser for Ruby. Because it parses phrases such as the ones described above you can incorporate English language phrases into your gherkin which can be easily parsed out in your step definitions. Lets examine what the step definitions for our example above using Chronic look like:Scenario: Scheduling a follow-up appointment after a sale Given(^an employee is hired "(.*?)"$/) do |hire_date_s| @hire_date = Chronic.parse(hire_date_s) end When(^I schedule a review$/) do @review_scheduler.schedule(@hire_date) end Then(^the review should be scheduled for "(.*?)"$/) do |expected_review_date_s| expected_review_date = Chronic.parse(expected_review_date_s) Review.where("review_date = :review_date", {:review_date => expected_review_date}).exists?.should be true end #other steps
This is a maintainable solution which has the benefit of being in English. Lets say that instead of "90 days from now" your product owner changes his mind and decides that he want to schedule a review "60 days from today at noon". Chronic can handle the time aspect just as easily using the exact same step definition.
Here are some other examples of what Chronic can do (execute from irb):
1.8.7 :001 > require 'rubygems' => true 1.8.7 :002 > require 'chronic' => true 1.8.7 :003 > Chronic.parse('the second Tuesday July 2014') => Tue Jul 02 20:14:00 -0400 2013 1.8.7 :004 > Chronic.parse('five months ago') => Thu Jan 17 21:41:29 -0500 2013 1.8.7 :014 > Chronic.parse("one week from today at noon") => Mon Jun 24 12:00:00 -0400 2013 1.8.7 :015 > Chronic.parse("8 hours ago") => Mon Jun 17 14:00:02 -0400 2013
These are just a few examples what Chronic is capable of, but as you can see it greatly increases your ability to write maintainable, user-friendly gherkin using the English language.
No comments:
Post a Comment