0

我最近开始从事一个使用 Ruby+Minitest 的自动化测试项目,我想知道我是否可以运行 1 次测试,其次数是我提供的输入数据的次数。

所以,我有点喜欢(代码在保密协议下,所以我不能提供真实的例子)

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

诀窍是,在process_new_entry方法内部有一个循环,我很高兴摆脱它,只需运行这个测试,其次数与list_entries

在 Java+Selenium 中的 TestNG 中,我想起了使用数据提供程序的概念,该数据提供程序在测试方法中逐个传递输入数据。有没有可能在这里实施类似的方法?

4

1 回答 1

0

如果你有:

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

而你真的想在自己的测试中运行每个案例,那么它只是:

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

如果您真的想拥有与 Java 完全相同的语法,可以将上面的内容转换为库,这样就可以了:

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

但我没有看到对它如此间接/抽象的好处。我建议保持明确,保持代码和执行状态可检查且易于调试:

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
于 2020-07-25T23:17:49.890 回答