Time Bombs
Definition:
Tests that fail due to ever-so-slightly different time values, during certain days of the week or month, or when a long-running time-sensitive test straddles two hours, days, weeks, months, or years and the code can’t handle it.
Code Example:
# Subject under test
require 'bigdecimal'
require 'bigdecimal/util'
class TimeCard
attr_reader :start_time, :end_time
def initialize(hourly_wage)
@hourly_wage = hourly_wage
end
def punch_in(at = nil)
@start_time = at || Time.new
end
def punch_out(at = nil)
@end_time = at || Time.new
end
def wage_owed
seconds = (@end_time || Time.new) - @start_time
hours = seconds / (60 * 60).to_d
bonus = worked_on_weekend? ? 1.5 : 1
@hourly_wage * hours * bonus
end
end
# Test
class TimeBombs < SmellTest
include UnreliableMinitestPlugin
def setup
@subject = TimeCard.new(15)
@now = Time.new
super
end
def test_punch_in_defaults_to_now
@subject.punch_in
assert_equal @subject.start_time.to_ms, @now.to_ms
end
def test_calculates_wage_owed
@subject.punch_in(@now)
@subject.punch_out(@now + (60 * 60 * 24))
result = @subject.wage_owed
assert_equal 360, result.to_i
end
end
# Fake production implementations to simplify example test of subject
class TimeCard
def worked_on_weekend?
return @start_time.wday === 0 ||
@start_time.wday === 6 ||
@end_time.wday === 0 ||
@end_time.wday === 6
end
end
References:
Quality attributes
- Code Example
- Cause and Effect
- Frequency
- Refactoring