3

如果你写一个像这样的测试类

class MyTest < Test::Unit::TestCase 
  def setup 
  end

  def test_1 
    flunk
  end

  def test_1 
    assert true
  end
end

第一个 test_1 被忽略。尽管这看起来像一个愚蠢的错误,但它可能发生在复制和粘贴编程中。除了跑步

grep test test_me.rb | wc

并将其与测试单元运行的测试数量、使用 rcov 或 heckle 或使用 -w 运行进行比较,您如何检测到此类问题?

另外,有没有办法指定测试方法不应该被覆盖?

编辑:被测试的方法有一个带有 6 个左右可能值的参数,测试人员想要测试每个场景。这就是使用复制和粘贴编程的原因。对于这种情况,我可以设想的唯一替代方案是参数和预期值的六元素数组。

4

6 回答 6

5

您可以利用在method_added任何时候将方法添加到类中时都会调用的 Ruby。您应该能够将某些内容放入您包含的模块中,但这里有一个在您的测试类中执行此操作的简单示例。

class MyTest < Test::Unit::TestCase

  @@my_tests = []

  def self.method_added(sym)
    raise "#{sym} already defined!" if @@my_tests.include? sym
    @my_tests << sym
  end

  def test_foo_1
  end

  def test_foo_2
  end

  def test_foo_1
  end
end
于 2009-02-20T17:44:07.067 回答
2

编辑:被测试的方法有一个带有 6 个左右可能值的参数,测试人员想要测试每个场景。这就是使用复制和粘贴编程的原因。

在这种情况下,我这样做:

def test_foo
  test_cases = [
   {:param => 1, :expected => 'whatever is expected'},
   {:param => 2, :expected => 'whatever is expected'},
   {:param => 3, :expected => 'whatever is expected'},
   {:param => 4, :expected => 'whatever is expected'},
   {:param => 5, :expected => 'whatever is expected'},
   {:param => 6, :expected => 'whatever is expected'}
  ]

  for test_case in test_cases
    do_the_test(test_case)
  end
end

def do_the_test(test_case)
  # test code here
end

这完全避免了复制和粘贴,正如已经说过的那样,这是不好的

对于这种情况,我可以设想的唯一替代方案是参数和预期值的六元素数组。

确切地!

于 2009-02-21T10:00:58.840 回答
2

关于 HermanD 的回答,既然这是 Ruby!,您也可以直接在类中执行此操作以创建独特的测试方法:

class MyObjectTest < Test::Unit::TestCase
  [
   {:param => 1, :expected => 'whatever is expected'},
   {:param => 2, :expected => 'whatever is expected'},
   {:param => 3, :expected => 'whatever is expected'},
   {:param => 4, :expected => 'whatever is expected'},
   {:param => 5, :expected => 'whatever is expected'},
   {:param => 6, :expected => 'whatever is expected'}
  ].each do |test_case|
    define_method :"test_using_#{test_case[:param]}_should_return_#{params[:expected].underscore}" do
      assert_equal test_case[:expected], MyObject.new.do_something_with(test_case[:param])
    end
  end
end

使用 Rspec(或 Shoulda 的)句子之类的语言感觉更自然:

describe MyObject do
   [
   {:param => 1, :expected => 'whatever is expected'},
   {:param => 2, :expected => 'whatever is expected'},
   {:param => 3, :expected => 'whatever is expected'},
   {:param => 4, :expected => 'whatever is expected'},
   {:param => 5, :expected => 'whatever is expected'},
   {:param => 6, :expected => 'whatever is expected'}
  ].each do |test_case|
    it "should return #{test_case[:expected]} when using #{test_case[:param]}" do
      MyObject.new.do_something_with(test_case[:param]).should == test_case[:expected]
    end
  end
end
于 2009-02-21T12:32:20.740 回答
1

如果您为测试提供正确的描述性名称,这真的是个问题吗?这是我最近项目中一些测试方法名称的示例:

test_should_not_do_html_escaping_for_administrators
test_should_not_be_able_to_create_project_with_company_user_doesnt_own
test_should_be_able_to_edit_own_projects
test_should_not_be_able_to_edit_others_projects

如果您的测试名称足够短,以至于您可以轻松地覆盖或复制它们,那么您可能没有足够描述您在每个测试中实际测试的内容。

于 2009-02-19T23:16:09.303 回答
0

避免复制粘贴编程。如果必须,重新绑定快捷键。

于 2009-02-20T12:16:54.590 回答
0

gem 版本的 test-unit 能够检测从2.0.7开始重新定义的测试。

于 2010-03-09T22:49:48.300 回答