我在新的Rails项目中使用MiniTest,这是我第一次真正进行测试。当测试失败时,消息看起来像这样
1) Failure:
Category::when created#test_0002_must have a unique name [/home/caleb/workspace/buzz/test/models/category_test.rb:10]:
Expected: true
Actual: false
您可以将#test_0002_更改为另一个字符串以使错误更具可读性吗?我知道这是一个小问题,但这似乎应该得到支持。
# Example test
require 'test_helper'
describe Category do
describe 'when created' do
unique = false
it 'must not have a unique name' do
unique.must_equal false
end
it 'must have a unique name' do
unique.must_equal true
end
end
end
答案 0 :(得分:4)
嗯,这里有很多东西需要报道,所以请耐心等待。
首先,测试名称是可读的。而且它们是100%准确的。当您使用规范DSL时,您仍然在创建测试类和测试方法。在您的情况下,您的课程为Category::when created
,您的考试方法为test_0002_must have a unique name
。它们之间的#
是一个非常常见的Ruby习语,用于类的实例方法,这是您的测试方法。当您使用class
或def
时,您无法创建包含空格的类或方法,但是当您以编程方式创建它们时,您可以。运行代码时,Ruby不关心它们是否有空格。
其次,我们可以影响测试类和方法的显示。该文本来自对Minitest::Test#to_s
的调用。这是看起来像:
def to_s # :nodoc:
return location if passed? and not skipped?
failures.map { |failure|
"#{failure.result_label}:\n#{self.location}:\n#{failure.message}\n"
}.join "\n"
end
当测试失败时,将返回更多信息,包括失败的原因。但我们关心的是location
。这是看起来像:
def location
loc = " [#{self.failure.location}]" unless passed? or error?
"#{self.class}##{self.name}#{loc}"
end
啊,更好。在最后一行,您可以清楚地看到它正在打印类和方法名称。如果测试失败,则该位置还包括定义方法的文件名。让我们打破这些值,使它们不是内联的:
def location
loc = " [#{self.failure.location}]" unless passed? or error?
test_class = self.class
test_name = self.name
"#{test_class}##{test_name}#{loc}"
end
好的,更清楚一点。首先是测试类,然后是#
,然后是测试名称,然后是测试未通过的位置。现在我们已经将它们分解了,我们可以稍微修改它们。让我们使用/
来分隔类名称空间和测试方法:
def location
loc = " [#{self.failure.location}]" unless passed? or error?
test_class = self.class.to_s.gsub "::", " / "
test_name = self.name
"#{test_class} / #{test_name}#{loc}"
end
大。现在让我们从测试方法的开头删除test_0002_
。这是由规范DSL添加的,通过删除它我们可以使它匹配传递给it
块的字符串:
def location
loc = " [#{self.failure.location}]" unless passed? or error?
test_class = self.class.to_s.gsub "::", " / "
test_name = self.name.to_s.gsub /\Atest_\d{4,}_/, ""
"#{test_class} / #{test_name}#{loc}"
end
现在,您的测试输出将如下所示:
1) Failure:
Category / when created / must have a unique name [/home/caleb/workspace/buzz/test/models/category_test.rb:10]:
Expected: true
Actual: false
Minitest与任何其他Ruby库没什么不同。规范DSL只是一个用于创建测试类和方法的瘦包装器。您可以改变测试对象的行为,使其按照您希望的方式工作。
TL; DR 将以下内容添加到test/test_helper.rb
文件中:
class Minitest::Test
def location
loc = " [#{self.failure.location}]" unless passed? or error?
test_class = self.class.to_s.gsub "::", " / "
test_name = self.name.to_s.gsub /\Atest_\d{4,}_/, ""
"#{test_class} / #{test_name}#{loc}"
end
end