为什么MiniTest :: Spec没有wont_raise断言?

mat*_*att 32 ruby unit-testing minitest

Ruby Test::Unitassert_nothing_raised.Test::Unit已被MiniTest取代.为什么MiniTest的断言/期望与此没有任何平行?例如,你可以期待,must_raise但不是wont_raise.

mat*_*att 48

MiniTest确实assert_nothing_raised在其Test :: Unit兼容层中实现,但在它自己的测试(MiniTest::UnitMiniTest::Spec)中它没有实现这样的任何测试.原因是,程序员认为,对所引发的任何事情的测试都不是对任何事情的考验; 你从来不指望什么在测试得到提升,当您正在测试,除了例外.如果测试代码中出现意外(未捕获)异常,您将在测试中按顺序报告异常,并且您将知道存在问题.

例:

require 'minitest/autorun'

describe "something" do
  it "does something" do
    Ooops
  end
end
Run Code Online (Sandbox Code Playgroud)

输出:

Run options: --seed 41521

# Running tests:

E

Finished tests in 0.000729s, 1371.7421 tests/s, 0.0000 assertions/s.

  1) Error:
test_0001_does_something(something):
NameError: uninitialized constant Ooops
    untitled:5:in `block (2 levels) in <main>'

1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
Run Code Online (Sandbox Code Playgroud)

这正是你想知道的.如果你没有想要什么可以被提出,你就没有得到它而你已经被告知了.

所以,这里的论点是:不要使用assert_nothing_raised!这只是一个毫无意义的拐杖.例如,见:

https://github.com/seattlerb/minitest/issues/70

https://github.com/seattlerb/minitest/issues/159

http://blog.zenspider.com/blog/2012/01/assert_nothing_tested.html

另一方面,显然assert_nothing_raised对应于用户之间的一些直觉,因为很多人都期望wont_raise与之相关must_raise等等.特别是人们希望将这一断言集中于此,而不仅仅是测试.幸运的是,MiniTest非常极简和灵活,所以如果你想添加自己的例程,你可以.因此,您可以编写一个无异常测试的方法,如果没有异常则返回已知结果,现在您可以断言该已知结果.

例如(我不是说这是完美的,只是表明了这个想法):

class TestMyRequire < MiniTest::Spec
  def testForError # pass me a block and I'll tell you if it raised
    yield
    "ok"
  rescue
    $!
  end
  it "blends" do
    testForError do
      something_or_other
    end.must_equal "ok"
  end
end
Run Code Online (Sandbox Code Playgroud)

关键不在于这是一个好的或坏的想法,但MiniTest从来没有责任为你做这件事.

  • 很好的答案.`assert_nothing_raised`是一个noop.你最好避免它.从他的博客文章中了解zenspider的评论:"这正是为什么minitest没有'assert_nothing_raised`.你最终得到了无用的垃圾测试文件." (3认同)
  • 虽然严格意义上说这是真的,如果你在没有断言的情况下编写测试,只是为了确保代码不会抛出错误,你可能会添加一条评论说"这不应该引发错误",所以有一个断言似乎更一致,以免我们抛弃所有这些,因为`assert`是你真正需要的唯一一个......`assert_false` - >使用`!`; `assert_equal` - >使用`==`; 等......这都是语法糖. (3认同)

daz*_*nic 10

如果你需要它:

# test_helper.rb

module Minitest::Assertions
  def assert_nothing_raised(*)
    yield
  end
end
Run Code Online (Sandbox Code Playgroud)

并使用它:

def test_unknown_setter
  assert_nothing_raised do
    result.some_silly_column_name = 'value'
  end
end
Run Code Online (Sandbox Code Playgroud)

  • 好一个!我是猴子补丁的忠实粉丝。 (2认同)