November 5, 2011

Bulk view

Quantified Awesome: Development-driven behaviour and integrated tests for life

2011-12-14: Updated step code

In terms of testing code, behaviour-driven development is fantastic. You can write your tests in pretty much plain English using a testing tool like Cucumber for Rails, which makes it easier to communicate with other people (including clients!). There’s a certain satisfaction in getting your tests to pass, and when they break, you know something needs fixing.

I’ve been thinking about what automated tests might look like in life. It turned out to be easy to prototype, thanks to the data I’m already collecting. It’s almost like development-driven behavior: can I apply the tools I use in software development to help me change my behaviours in life?

Here are some results from my very first integration test of real life:

Feature: Development-driven behaviour

  Scenario: Check for overdue books                # features/life.feature:2
    When I check our library items                 # features/step_definitions/life.rb:3
    Then there should be no items that are overdue # features/step_definitions/life.rb:7

  Scenario: Check my work load                       # features/life.feature:5
    When I look at my time use for the past 7 days   # features/step_definitions/life.rb:11
    Then I should have time data                     # features/step_definitions/life.rb:19
    And I should have worked between 40 and 44 hours # features/step_definitions/life.rb:24
      <46.5166666666667> expected to be
      <=
      <44.0>. (Test::Unit::AssertionFailedError)
      ./features/step_definitions/life.rb:26:in `/^I should have worked between (\d+) and (\d+) hours$/'
      features/life.feature:8:in `And I should have worked between 40 and 44 hours'

  Scenario: Check if I'm sleeping                        # features/life.feature:9
    When I look at my time use for the past 7 days       # features/step_definitions/life.rb:11
    Then I should have slept between 8 and 9 hours a day # features/step_definitions/life.rb:29

Failing Scenarios:
cucumber features/life.feature:5 # Scenario: Check my work load

3 scenarios (1 failed, 2 passed)
7 steps (1 failed, 6 passed)
0m0.833s

Cucumber highlights failing tests in red and it lists the failures as well.

Here’s the steps.rb that I’ve started fleshing out:


When /^I look at my time use for the past (\d+) days?$/ do |arg1|
  @start_time = (Date.today - arg1.to_i.days).midnight.in_time_zone
  @end_time = Date.today.midnight.in_time_zone
  @log = TimeTrackerLog.new(User.first)
  @entries = @log.entries(@start_time, @end_time)
  @summary = @log.summarize(@start_time, @end_time)
end

Then /^I should have time data$/ do
  assert @entries != nil
  assert @entries.size > 0
end

Then /^I should have worked between (\d+) and (\d+) hours$/ do |min, max|
  assert_operator @summary['A - Work'] / 1.hour, :>=, min.to_f
  assert_operator @summary['A - Work'] / 1.hour, :< =, max.to_f
end

Then /^I should have slept between (\d+) and (\d+) hours a day$/ do |min, max|
  average = @summary['A - Sleep'] * 1.0 / (1.hour * ((@end_time - @start_time) / 1.day))
  assert_operator average, :>=, min.to_f
  assert_operator average, :< =, max.to_f
end

# LIBRARY

When /^I check our library items$/ do
  nil # Actually stored in database, so we don't need anything here. This is more for semantics
end

Then /^there should be no items that are overdue$/ do
  assert_equal 0, LibraryItem.where('status = ? AND due < ?', 'due', Date.today).size
end

I am pleasantly boggled that this is possible, and will probably write all sorts of odd tests now. Because Cucumber can fill in web forms, click on stuff, and so on, I might even be able to use it to check information on other sites. (When I check my mail, then all the messages in my inbox should be less than a week old?)

Oh, the possibilities…

Weekly review: Week ending November 4, 2011

I worked 46 hours this week. Most of the overtime was from a 12-hour sprint on Tuesday, getting all our tests to run again after weeks of collective neglect. I tried to cut back on work on Thursday and Friday. Between meetings and my own desire to make good progress, I ended up working a regular day.

I don’t feel particularly time-deprived this week. I’ve made good progress on a stuff-tracking component for my personal dashboard, and I’ve improved the tracker for community-supported agriculture produce. I read lots of books. We hosted another study group, too. I’ve prepared lots of food for the coming week.

My bottleneck is more like energy and interest, not raw time. A lot of things are down on my list. Working long hours on client projects means being less inclined to spend additional hours on extracurricular work stuff. I’ll see if I can work out a lighter work week next week so that I can save time and energy for these things. In particular, the Lotus Connections Toolkit is one of those high-leverage things – a little effort can go a long way.

Maybe my time analysis will help me see where the time came from. Hmm…

From last week’s plans

  • Work
    • [X] Project O: Lots more work
    • [X] Project I: Follow up on SQL Server changes
    • [-] Project T: Follow up on pre-launch – meeting next week
    • [-] Prototype flashcards – probably Rails
    • Submitted annual results
    • Shared lots of visualization examples
  • Relationships
    • [X] Facilitate another fun study group
    • [-] Help J- with writing – maybe next week
  • Life
    • [X] Have massage!
    • [X] Write about more quantified self stuff
    • [X] Find other quantified self bloggers
    • [X] Improve measurements for home dashboard – added summary
    • Added stuff tracking to dashboard
    • Improved CSA tracking

Plans for next week

  • Work
    • [ ] Work on project O: write more tests
    • [ ] Project O: get e-mail templates finally sorted out
    • [ ] Get project T closer to launching
    • [ ] Prototype flashcards
    • [ ] Work on Lotus Connections Toolkit migration
  • Relationships
    • [ ] Have Maira and Scott over for board games?
    • [ ] Help out with home renovation planning
    • [ ] Follow up on things Mom was interested in
  • Life
    • [ ] Make lots of food
    • [ ] Continue tracking stuff

Time analysis

Activity Sat Sun Mon Tue Wed Thu Fri Total Average Weekday average Weekend average
Sleep 8.0 6.9 7.9 7.0 7.2 7.9 5.7 50.7 7.2 7.2 7.4
Work 0.0 1.1 8.2 12.6 9.8 7.7 7.2 46.5 6.6 9.1 0.5
Discretionary 5.6 6.3 4.5 1.6 3.5 1.9 9.0 32.4 4.6 4.1 5.9
Unpaid work 1.7 7.8 0.5 1.0 1.6 3.0 0.6 16.2 2.3 1.3 4.8
Personal care 8.7 2.0 2.8 1.7 1.9 3.5 1.6 22.2 3.2 2.3 5.3
Activity This week Last week Delta Notes
Discretionary 32.4 37.5 -5.1
Personal care 22.2 12.6 9.6
Unpaid work 16.2 12.2 4.0
Sleep 50.7 61.1 -10.5
Work 46.5 44.5 2.0 Extra time getting tests to pass
D – Break 1.3 -1.3
D – Drawing 0.1 0.7 -0.6
D – Other 9.4 0.1 9.2 Worked on personal tracking system
D – Personal 0.6 6.6 -6.0
D – Reading 4.9 4.4 0.5
D – Shopping 2.1 2.1 0.1
D – Social 4.3 17.1 -12.8
D – Writing 11.1 5.3 5.8 Made time for this
P – Eating 1.9 1.3 0.6
P – Exercise 11.3 1.8 9.5 Biking on weekends, walking to subway for work
P – Routines 8.9 9.5 -0.6 Pre-cooked oatmeal saves a little bit of time, but not much
UW – Cooking 9.0 1.9 7.2 Processed the vegetables, prepared lamb korma
UW – Tidying 4.6 6.6 -2.0
UW – Travel 2.6 3.7 -1.2 Worked from home one day, biked to work another day

So it looks like most of the extra time got moved from sleep, hobbies, and socialization. We didn’t have J- this week, so we spent less time helping her with homework (just the Friday study group). I made more time to write, which felt good. I’m also experimenting with doing more up-front cooking instead of waiting until our home-made frozen lunches dwindle, so I spent more time cooking this week.

I’d like to get work under control next week. This probably involves comparing the relief and happiness I can get by scratching the itch in my brain (bugs, tests that still need work…) versus other things that might have less immediate but still valuable payoff (working on my personal projects, investing in relationships). It seems like an excellent idea to work when something’s taking up brainspace so that I can get it out of my head, but there’s always more work to do. Solving one issue leads to another, and another, and another. Work can pose an infinite number of challenges with short-term payoffs. Down this path lies a dangerous temptation to neglect other things, though, so I think it might be more useful to get better at putting those brain-itches into perspective.

I’m sure that if I sit down and make space to think about it, I can come up with ideas for non-work activities that create even more value. I need to externalize that list, because it can be hard to compare a clearly-defined work task (solve issue X in our queue) with a vague idea that I may want to spend more time on relationships or personal projects. It can be difficult to admit that some clearly-defined tasks (ex: get the Lotus Connections Toolkit working again) end up with lower priorities than exploratory tasks (ex: do a freezer audit and nudge us closer to a better finished meals:frozen ingredients ratio).

There’s also the risk of procrastinating things that are really worth doing. At some point, the mental cost of carrying these ideas around (or even stashing them in one’s to-do list) outweighs the benefits of other activities. Still, it’s a good idea to make sure your priorities strongly influence how you spend your time, particularly when work is so fun that it can suck you into flow experiences. Flow isn’t bad, but it’s also not always good.

I’ve circled around this idea for several paragraphs now, so there’s probably something here that I need to pay attention to. Hmm.

Also, wake-up times have edged forward a little bit. Let’s see how the end of Daylight Savings Time changes things, too.