This may have been discussed before but just wanted to pass along a killer one-two punch that we stumbled upon as an excellent and natural extension to our domain language around the expression and testing of complex time based constructs. Please consider: Cucumber allows you to specify behavior in natural language. Chronic is a natural language date/time parser written in pure Ruby. (http://chronic.rubyforge.org/) Example of a cucumber test: Scenario: Test control operations Given that I have have a control operation named ?set clock date time? to ?Monday Jan 1, 2009 10:00? When the control named ?set clock date time? runs Then the clock should be ?10:00? Now, this works fine, if you?re only testing that you can set the clock to "Monday Jan 1, 2009 10:00". It gets more complex quickly when you try to do much more than this. Adding chronic to the mix allows us to define and use more complex time concepts in plain language. This allows for the parsing of sentence fragments such as ?next month? and ?next Tuesday? and combine them in to complex structures such as ?next Tuesday at 9:00? in a way that our tests continue to run as time marches on. For example:>> sentence = "next tuesday at 3:00 pm"=> "next tuesday at 3:00 pm">> time = Chronic.parse(sentence)=> Tue Mar 03 15:00:00 -0700 2009 Now, the scenario can use this easily express clearly ?when? the control operation runs in more complex and useful expressions, for example: Scenario: Test control operations Given that I have have a control operation named ?set clock date time? to "next tuesday at 3:00 pm" When the control named ?set clock date time? runs Then the clock should be ?next tuesday at 3:00 pm" Scenario: Test spy sweeping schedules Given that I have have a control operation named ?clean spies? that is scheduled to run ?next Monday at 8:00 AM" And the customer has excluded ?weekdays? from allowing the control operation ?clean spies? to run When the control named ?set clock time? runs Then it should log a message and quit
On Sun, Mar 1, 2009 at 8:50 AM, Tim Walker <walketim at gmail.com> wrote:> > Now, this works fine, if you?re only testing that you can set the > clock to "Monday Jan 1, 2009 10:00". It gets more complex quickly when > you try to do much more than this. Adding chronic to the mix allows us > to define and use more complex time concepts in plain language. This > allows for the parsing of sentence fragments such as ?next month? and > ?next Tuesday? and combine them in to complex structures such as ?next > Tuesday at 9:00? in a way that our tests continue to run as time > marches on. > > For example: >>> sentence = "next tuesday at 3:00 pm" > => "next tuesday at 3:00 pm" >>> time = Chronic.parse(sentence) > => Tue Mar 03 15:00:00 -0700 2009Just be careful when when basing durations from "now" that daylight savings time doesn''t affect anything. ///ark
On Sun, Mar 1, 2009 at 11:07 AM, Mark Wilden <mark at mwilden.com> wrote:> > Just be careful when when basing durations from "now" that daylight > savings time doesn''t affect anything.Along the same lines, don''t write tests that assume 1.month.ago was < 29 days ago, or specs could start failing in March (as just happened with us). :) ///ark
On Sun, Mar 1, 2009 at 6:30 PM, Mark Wilden <mark at mwilden.com> wrote:> On Sun, Mar 1, 2009 at 11:07 AM, Mark Wilden <mark at mwilden.com> wrote: >> >> Just be careful when when basing durations from "now" that daylight >> savings time doesn''t affect anything. > > Along the same lines, don''t write tests that assume 1.month.ago was < > 29 days ago, or specs could start failing in March (as just happened > with us). :)You wouldn''t happen to be on the Microsoft Zune development team, would you? >8-> For date testing, I''ve just discovered and successfully used Notahat''s "time_travel" plugin: http://github.com/notahat/time_travel/ It''s essentially a scoped override for Time.now, so that any code you pass it executes as if the current time is frozen at whatever you tell it. This makes repeatable testing much, much simpler. This is the same guy who developed Machinist (my preferred fixture/factory tool) and not_a_mock, which I used for a little while before I abandoned mocking. >8-> So...yeah. He does good stuff. -- Have Fun, Steve Eley (sfeley at gmail.com) ESCAPE POD - The Science Fiction Podcast Magazine http://www.escapepod.org
On Sun, Mar 1, 2009 at 9:07 PM, Stephen Eley <sfeley at gmail.com> wrote:> > For date testing, I''ve just discovered and successfully used Notahat''s > "time_travel" plugin: > http://github.com/notahat/time_travel/We have just been stubbing Time.now, but I''ll think about time_travel. One advantage would be not having to "manually" reset RSpec mocks after each Cucumber scenario is run in After. ///ark
Absolutely. I''d respectfully suggest that this is more a requirement of the way the step definition or test fixture that implements the feature needs to behave than the intent of describing time based logic in a natural language such that product owners, ba''s etc. can write them (i.e. Cucumber, FitNesse, etc). That Chronic takes into consideration the things you mention (time zone, DST, Leap Years, etc), is simply an imperative of it. Anyway, I think it fits hand-in-glve with Cucumber and BDD in general. Just for the record, I have no vested interest in Chronic and really don''t know who even authored it, but I can say it''s looking pretty awesome in our own Cucumber tests. Thanks, Tim On Sun, Mar 1, 2009 at 4:30 PM, Mark Wilden <mark at mwilden.com> wrote:> On Sun, Mar 1, 2009 at 11:07 AM, Mark Wilden <mark at mwilden.com> wrote: >> >> Just be careful when when basing durations from "now" that daylight >> savings time doesn''t affect anything. > > Along the same lines, don''t write tests that assume 1.month.ago was < > 29 days ago, or specs could start failing in March (as just happened > with us). :) > > ///ark > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On Sun, Mar 1, 2009 at 11:07 AM, Mark Wilden <mark at mwilden.com> wrote:> > Just be careful when when basing durations from "now" that daylight > savings time doesn''t affect anything.Like it did today, when two specs that used ''Time.now.advance(:hours => 24).utc'' started failing. ///ark