如何解决最小测试在纯功能上比较脆弱,没有副作用
由于我下周加入了Rails项目(是的!),所以我正在做RomanNumerals kata作为我的工具的精简版,但是我编写的测试随机失败(嘘!)。
- 每次让它们运行时,只要不更改代码,我都会得到不同的结果。
- 我正在使用
rails test
作为命令。 - 这些版本都是最新版本。来自
rails new
的所有内容都没有任何其他宝石。 (Ruby 2.7.0,Rails 6.0.3)
在并行运行的测试与一些变量被其他测试覆盖之间似乎有些奇怪的混合。也许有一些奇怪的优化事情涉及到正在进行的缓存?
Running via Spring preloader in process 18166
Run options: --seed 29967
# Running:
.......F
Failure:
RomanNumeralHelperTest#test_18_returns_XVIII [/home/eric/rails/rome/test/helpers/roman_numeral_helper_test.rb:55]:
Expected: "XVIII"
Actual: "IXVIII"
rails test test/helpers/roman_numeral_helper_test.rb:54
........
Finished in 0.066531s,240.4883 runs/s,240.4883 assertions/s.
16 runs,16 assertions,1 failures,0 errors,0 skips
Running via Spring preloader in process 18195
Run options: --seed 59433
# Running:
.............F
Failure:
RomanNumeralHelperTest#test_15_returns_XV [/home/eric/rails/rome/test/helpers/roman_numeral_helper_test.rb:51]:
Expected: "XV"
Actual: "IXV"
rails test test/helpers/roman_numeral_helper_test.rb:50
..
Finished in 0.053298s,300.2008 runs/s,300.2008 assertions/s.
16 runs,0 skips
Running via Spring preloader in process 18247
Run options: --seed 14645
# Running:
................
Finished in 0.048711s,328.4691 runs/s,328.4691 assertions/s.
16 runs,0 failures,0 skips
class RomanNumeralHelperTest < ActiveSupport::TestCase
test "1 returns I" do
assert_equal "I",RomanNumeralHelper.convert(1)
end
test "2 returns II" do
assert_equal "II",RomanNumeralHelper.convert(2)
end
test "3 returns III" do
assert_equal "III",RomanNumeralHelper.convert(3)
end
# Intermittent tests omitted. They go from 1 to 20.
test "20 returns XX" do
assert_equal "XX",RomanNumeralHelper.convert(20)
end
end
module RomanNumeralHelper
ROMAN_ONE = "I"
ROMAN_FIVE = "V"
ROMAN_TEN = "X"
def self.convert(number)
result = ""
current_numeral = ""
remaining_number = number
until remaining_number == 0 do
if remaining_number > 8
current_numeral = ROMAN_TEN
remaining_number -= 10
elsif remaining_number > 3
current_numeral += ROMAN_FIVE
remaining_number -= 5
else
result += ROMAN_ONE * remaining_number
remaining_number = 0
end
if remaining_number < 0
current_numeral.prepend(ROMAN_ONE)
remaining_number = 0
end
result += current_numeral
current_numeral = ""
end
result
end
end
解决方法
我的错误是修改常量。
current_numeral = ROMAN_TEN
current_numeral.prepend(ROMAN_ONE)
我更改了ROMAN_TEN引用的字符串。解决方法是:
ROMAN_TEN = "X".freeze
和
current_numeral = ROMAN_TEN.dup
即使在像这样的小项目上使用rubocop,也会给我警告。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。