Is there a possibility to write parametrized tests with Ruby+Minitest?

344 Views Asked by At

I've recently started working on a automated testing project, that uses Ruby+Minitest and I wonder if I can run 1 test as many times as many input data I provide.

So, I have smth like (code is under NDA so I can't provide real examples)

def test_new_registrations
  result = process_new_entry(list_entries)
  assert(validator_method(result), result)
end

The trick is that inside process_new_entry method there's a loop I'm glad to get rid of and just run this test as many times as many entries are there on the list_entries

From TestNG in Java+Selenium I recall a concept of using a dataprovider which passes input data inside the test method one by one. Is there any chance a simmilar approach can be implemented here?

1

There are 1 best solutions below

1
On BEST ANSWER

If you have:

class MyTest
  TESTCASES = {
    # input => expected
    a: "a",
    b: "b",
    c: "c",
  }

  def test_testcases
    TESTCASES.each do |entry, expected|
      result = process_one(entry)
      assert(expected, result)
    end
  end
end

And you really want to run each case in its own test instead, then it's just:

MyTest
  TESTCASES = {
    # input => expected
    a: "a",
    b: "b",
    c: "c",
  }

  TESTCASES.each do |entry, expected|
    define_method("test_testcase_#{entry}") do
      result = process_one(entry)
      assert(expected, result)
    end
  end
end

If you REALLY wanted to have the exact same syntax as in Java, it'd be possible to convert the above into a library so that this would work:

testcase_parameters(TESTCASES) # left as an exercise to the reader
def test_testcase(entry, expected)
  assert(expected, process_one(entry))
end

But I don't see the benefit of being so indirect/abstract about it. I would suggest to stay explicit, keeping the code and execution state inspect-able and easy to debug:

class MyTest
  TESTCASES = {
    # input => expected
    a: "a",
    b: "b",
    c: "c",
  }

  def test_testcases
    results = TESTCASES.map do |entry, expected|
      result = process_one(entry)
      [entry, [expected, result]]
    end

    invalid_results = results.select { |e, (ex, res)| ex != res }

    # This is a very easy-to-breakpoint place in code, to easily view all results:
    # binding.pry

    assert_empty invalid_results # failure cases will be printed out by test output
  end
end