gpt4 book ai didi

ruby - 使用 Ruby 和 Minitest,如何运行具有不同数据的相同测试用例,仅由列表控制

转载 作者:数据小太阳 更新时间:2023-10-29 06:34:39 24 4
gpt4 key购买 nike

我有对电话号码进行操作的 Ruby 2.0 代码,我想使用 MiniTest 对其进行测试。我有一个函数,它接受一个电话号码参数并对其进行测试(包括断言)。每次调用该函数时,我都希望它成为一个新的测试用例。像这样:

listOfPhoneNumbersForTesting.each { |phone|   testphone phone }  

我不想要的是:

class test2125551212 < MiniTest::Unit::TestCase
def t2125551212
testphone "2125551212"
end
end

...重复 10、20 或 100 次以测试每个电话号码...

显然,我可以将循环代码放在 MiniTest::Unit::TestCase 中,但无论我测试多少个电话号码,这都会导致只有一个测试用例,我不喜欢这样。 (此外,如果其中一个断言失败,则不再测试电话号码,我不想这样!)另外,第二种形式对我来说似乎违反了 DRY,因为类名、函数名和参数都包含电话号码。

不知何故,我觉得我应该能够拥有一个名为 TestPhone 的类,并使用电话号码参数创建它,并将其放入 MiniTest 框架中。但我愿意使用 setup()、Fixtures、元编程或任何其他东西,如果它可行的话。

listOfPhoneNumbersForTesting.each { |phone|   TestPhone.new phone }

其中 TestPhone 是 TestCase 的子类,最终调用 testphone 来完成工作。

基本上,我想要的是: 1. 一个电话号码列表,如果我向列表中添加一个号码,我会在报告输出中多获得一个 TestCase。 2.如果一个电话号码关联的测试失败,其余的仍然测试。 3. 所有电话号码都经过相同的测试,其中包括多个断言。

非常感谢!

最佳答案

您可以动态定义方法。

在下面的示例中,动态创建了 6 个测试(对被测试的 3 个值中的每一个值进行 2 个测试)。这意味着如果有任何失败,其他测试仍然会运行。

require "minitest/autorun"
class MyTests < MiniTest::Unit::TestCase
['0', '1111111', '2222222'].each do |phone_number|
define_method("test_#{phone_number}_has_7_characters") do
assert_equal(7, phone_number.length)
end

define_method("test_#{phone_number}_starts_with_1") do
assert_equal('1', phone_number[0])
end
end
end

应用测试用例给出以下结果:

# Running tests:

F..F.F

Finished tests in 0.044004s, 136.3512 tests/s, 136.3512 assertions/s.

1) Failure:
test_0_starts_with_1(MyTests) [stuff.rb:13]:
Expected: "1"
Actual: "0"

2) Failure:
test_0_has_7_characters(MyTests) [stuff.rb:9]:
Expected: 7
Actual: 1

3) Failure:
test_2222222_starts_with_1(MyTests) [stuff.rb:13]:
Expected: "1"
Actual: "2"

6 tests, 6 assertions, 3 failures, 0 errors, 0 skips

将相同的概念应用于您的测试,我认为您想要:

class MyTests < MiniTest::Unit::TestCase
listOfPhoneNumbersForTesting.each do |phone|
define_method("test_#{phone}") do
TestPhone.new phone
end
end
end

在使用规范式测试时可以采用类似的方法:

require 'minitest/spec'
require 'minitest/autorun'

describe "my tests" do
['0', '1111111', '2222222'].each do |phone_number|
it "#{phone_number} has 7 characters" do
assert_equal(7, phone_number.length)
end

it "#{phone_number} starts with 1" do
assert_equal('1', phone_number[0])
end
end
end

重要提示:需要注意的一件事是您需要确保创建的测试方法的名称对于每个测试用例都是唯一的。

例如,如果您不将电话号码放在方法名称中,您最终会覆盖以前定义的方法。最终,这意味着只会测试最后一个电话号码。

这是因为 MiniTest 动态生成测试方法并将覆盖已经生成的测试方法,最终只使用最后一个 .each 变量。

关于ruby - 使用 Ruby 和 Minitest,如何运行具有不同数据的相同测试用例,仅由列表控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18770988/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com