Ruby on rails 具有minitest的可读测试名称

Ruby on rails 具有minitest的可读测试名称,ruby-on-rails,automated-tests,minitest,Ruby On Rails,Automated Tests,Minitest,我正在一个新的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_uu更改为另一个字符串以使错误更具可

我正在一个新的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_uu更改为另一个字符串以使错误更具可读性?我知道这是个小问题,但这似乎应该得到支持

# 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

嗯,这里有很多要报道的,所以请容忍我

首先,测试名称是可读的。它们是100%准确的。当您使用specdsl时,您仍然在创建测试类和测试方法。在您的情况下,类是
Category::创建时
,测试方法是
test\u 0002\u必须具有唯一的名称
。它们之间的
#
是一个非常常见的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
def location
  loc = " [#{self.failure.location}]" unless passed? or error?
  "#{self.class}##{self.name}#{loc}"
end
当测试失败时,将返回更多信息,包括失败的原因。但我们关心的是
位置
。下面是它的样子:

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
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\u 0002\u
。这是由spec 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库没有什么不同。specdsl只是一个用于创建测试类和方法的薄包装器。您可以改变测试对象的行为,使其按照您希望的方式工作

TL;DR将以下内容添加到您的
test/test\u 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

嗯,这里有很多要报道的,所以请容忍我

首先,测试名称是可读的。它们是100%准确的。当您使用specdsl时,您仍然在创建测试类和测试方法。在您的情况下,类是
Category::创建时
,测试方法是
test\u 0002\u必须具有唯一的名称
。它们之间的
#
是一个非常常见的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
def location
  loc = " [#{self.failure.location}]" unless passed? or error?
  "#{self.class}##{self.name}#{loc}"
end
当测试失败时,将返回更多信息,包括失败的原因。但我们关心的是
位置
。下面是它的样子:

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
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\u 0002\u
。这是由spec 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库没有什么不同。specdsl只是一个用于创建测试类和方法的薄包装器。您可以改变测试对象的行为,使其按照您希望的方式工作

TL;DR将以下内容添加到您的
test/test\u 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

很棒的响应,我期待类似的东西,但我有点惊讶没有钩子或进程来提取测试名称格式。我想ruby的开放类使这些变得不必要了。这在最新版本的minitest(5.11.2)中有所改变。用于实际打印结果的代码已移动到
Result
类中,因此需要重写
Minitest::Result
location
方法。不确定这是否应该是它自己的答案,或者您只是更喜欢编辑您的sawesome响应,我希望这样,但我有点惊讶没有钩子或过程来提取测试名称格式。我想ruby的开放类使这些变得不必要了。这在最新版本的minitest(5.11.2)中有所改变。用于实际打印结果的代码已移动到
Result
类中,因此需要重写
Minitest::Result
location
方法。不确定这是否应该是它自己的答案,或者你只想编辑你的答案