Skip to content

Instantly share code, notes, and snippets.

@danking
Created September 11, 2010 05:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save danking/574852 to your computer and use it in GitHub Desktop.
Save danking/574852 to your computer and use it in GitHub Desktop.
require 'test/unit'
class ParameterizedTestCase < Test::Unit::TestCase
def self.suite
method_names = public_instance_methods(true)
target_method_names = method_names.find_all do |method_name|
method_name =~ /^ptest./
end
puts "target_method_names: #{target_method_names.inspect}"
parameterized_tests = collect_names_and_parameters(target_method_names)
puts "parameterized_tests: #{parameterized_tests.inspect}"
parameterized_tests.each do |test|
define_sub_tests(test)
end
super # on with TestCase's magic!
end
# define_sub_tests : ParameterizedTest ->
# defines the parameterized test's sub tests from the supplied parameters
def self.define_sub_tests(test)
test.parameters.each do |parameter|
if parameter[0].to_s.empty?
raise ArgumentError,
"One of #{method_name}'s parameters name's string representation" +
"is the empty string, this is not allowed."
end
if parameter.length - 1 != instance_method(test.name).arity
raise ArgumentError,
"#{method_name}'s #{parameter} parameter specifies " +
"#{parameter.length -1} arguments but #{method_name} takes " +
"#{instance_method(test.name).arity}"
end
define_method("test#{strip_ptest(test.name)}#{parameter[0]}".to_sym) do
__send__(test.name, *(parameter[1..parameter.length]))
end
end
end
private_class_method :define_sub_tests
# collect_names_and_parameters : [ArrayOf Symbol]
# -> [ArrayOf ParameterizedTest]
# collects the test method names and parameters into ParameterizedTest objects
def self.collect_names_and_parameters(target_method_names)
target_method_names.collect do |method_name|
parameter_name = "@@parameter#{strip_ptest(method_name)}".to_sym
puts "class_variables: #{class_variables}"
if class_variable_defined?(parameter_name)
ParameterizedTest.new(method_name, class_variable_get(parameter_name))
else
raise ArgumentError,
"#{method_name} is a parameterized test but has no parameters " +
"which would be named #{parameter_name}"
end
end
end
private_class_method :collect_names_and_parameters
# strip_ptest : Symbol -> String
# removes the 'ptest' prefix from the symbol and returns it as a string
def self.strip_ptest(method_name)
method_string = method_name.to_s
method_string.slice(5..method_string.length)
end
private_class_method :strip_ptest
end
class ParameterizedTest
attr_accessor :name, :parameters
def initialize(name, parameters)
@name = name
@parameters = parameters
end
end
##### I have this as another file in ../test
$LOAD_PATH << '../code'
require 'ParameterizedTestCase.rb'
class ParamterizedTestCaseTest < ParameterizedTestCase
@@parameter_parameterized = [['six', 6],
['nine', 9],
['eighty-one', 81]]
def ptest_parameterized(num)
assert num % 3 == 0
end
def test_normaltest
assert 42 == 42
end
def test_another_normaltest
assert_raise(ZeroDivisionError) { 1/0 }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment