In fuzzing my database for testing (see Fuzzing your Database and Faker), I've found the following to be very useful:
Object.class_eval do
def with_probability(prob, &block)
if rand <= prob
block.call
return ProbabilisticDoer::Done.new
else
return ProbabilisticDoer::NotDone.new
end
end
end
module ProbabilisticDoer
class NotDone
def else_with_probability(prob, &block)
with_probability(prob, &block)
end
def else(&block)
with_probability(1, &block)
end
end
class Done
def else_with_probability(prob, &block)
return self
end
def else(&block)
return self
end
end
end
With that, you can do things like
u = User.create(...)
with_probability(9/10.0) do
u.stuff_that_most_users_should_do
end
with_probability(0.01) do
u.stuff_that_very_few_users_should_do
end.else_with_probability(0.2) do
u.stuff_that_some_but_none_of_the_above_users_should_do
end.else do
u.stuff_the_rest_of_the_users_should_do
end