单元测试框架 - 主要特点是什么?

8

我已经阅读了很多关于可用的.NET单元测试框架的资料。对我来说不清楚的是,这些可用框架之间有哪些关键特性区别。在评估单元测试框架时,您寻找的必备功能是什么?

6个回答

2
这里是我关注的一些事项:
  • 速度。框架(和测试运行程序)并非都是平等的。如果您的单元测试滞后,您的生产时间就会浪费。
  • 断言。这些需要丰富多样,以提供许多情况。例如,您喜欢使用属性或 Assert.Throws 捕获异常吗?这些断言能否进行带指定公差的数值比较?
  • 其他杂项。某些框架具有有用的功能,例如行测试或能够以 XML 格式读取测试数据。

2
我所关注的是工具集支持,我特别优先考虑持续集成支持。对于单元测试来说(至少对我来说,不是TDD的狂热者),最重要的是将它们插入到我的CI构建服务器中。
因此,我更喜欢nUnit,因为在CruiseControl中有预先构建的构建任务,而这是我选择的构建服务器。这并不意味着你不能将任何其他测试框架插入到CC中,nUnit只是一个易于使用的框架。
至于可用功能,当你在后端使用价格合理的Visual Studio Team System和TFS运行MSTest时,它具有一些非常好的附加功能。
话虽如此,个人认为各个测试框架的功能差异并不大(我有xUnit、nUnit和MSTest的使用经验)——它们都允许你定义单元测试,并报告通过和失败的数量。它们都有某种形式的GUI,并且可以将它们全部与构建服务器集成。

1

我同意在断言和其他基本功能方面它们都非常相似。它们开始有所不同的地方在于更高级的选项,例如脚本框架、构建工具、自动化集成等。

如果您打算使用像CruiseControl.NET这样具有许多自定义构建选项和自定义脚本的高度自动化的构建过程,我可能会使用NUnit。它有更多的钩子可以根据测试结果触发其他操作。

如果您刚开始进行单元测试,并且只计划进行基本的集成测试,我建议使用MStest,因为它与Visual Studio 2008紧密集成。(NUnit有与IDE集成的选项,但更好的工具需要花费一些钱。)

这里是一个小比较表:

          | NUnit                            | MStest
---------------------------------------------------------------------------------
Asserts   | missing some collection asserts  | missing some numeric/date asserts
---------------------------------------------------------------------------------
Speed     | test run fast, faster setup on   | w/ VS 2008 no setup necessary on
          | servers and the like             | the client, test run fairly fast.
---------------------------------------------------------------------------------
Options   | a lot of 3rd party add-ons and   | some 3rd party tools
          | other tools                      |
---------------------------------------------------------------------------------
CC.NET    | good integration, lots of tools  | newer versions of CC.NET support
          | and options                      | MS test out of the box, not as
          |                                  | many add on tools
---------------------------------------------------------------------------------

你的表格缺少重要的行(至少对我来说)- 与TFS集成 - PiRX

0

在几乎所有测试框架中我都感到缺失的一件事是统一的断言,我的意思是无论我断言什么,测试应该看起来都一样。无论是对值进行基于状态的断言、对模拟对象进行基于行为的断言,还是断言应该抛出异常。

我将以Ruby为例,但这适用于任何环境。(另外,你不必局限于使用C#框架测试.NET应用程序,你可以使用任何.NET语言,其中当然包括Ruby,Python,Scheme,F#等)

这是使用Mocha进行模拟的test/unit(JUnit早期版本的移植)。

def test_state
  assert_equal 2, 1+1
end

def test_exception
  assert_raises(NoMethodError) { [].not_a_method }
end

def test_behavior
  o = Object.new
  o.expects(:ping).with(:pong)
  o.ping(:pong)
end

请注意所有断言的外观都不同,位置也不同,实际测试代码也分别位于三个不同的位置。
这就是Expectations,据我所知,它是唯一做得正确的框架。(事实上,它是专门为了统一断言而创建的。)不幸的是,由于作者不再从事Ruby工作,它已经不再得到维护或支持。
expect 2 do
  1+1
end

expect NoMethodError do
  [].not_a_method
end

expect Object.new.to.receive(:ping).with(:pong) do |o|
  o.ping(:pong)
end

请注意断言总是看起来一样,而且断言和测试代码总是在同一个位置。
不过,像xUnit.Net和Mockito这样的新框架已经越来越接近了。

0

面向开发人员的单元测试(请注意,我不是在谈论面向客户的验收测试!)就像生产代码一样:它们应该以明显的方式编写,以便清楚地了解它们正在做什么。实际上,这对于测试比生产代码更重要,因为对于生产代码,您有测试来告诉您代码是否有效,而对于测试,您只能阅读它们并查看它们是否有意义。

因此,面向开发人员的单元测试不应需要注释。而测试名称就是注释,因此,您的框架不应强制您命名测试。

以下是一个示例(在RSpec中,当然也可以在.NET上使用):

describe Array do
  it 'should be empty' do
    Array.new.should be_empty
  end
end

这太愚蠢了。任何需要测试名称才能理解此测试正在做什么的开发人员都应认真重新考虑自己的职业选择。此外,所有与注释相关的问题也同样适用:如果有人更改了测试但忘记更改名称怎么办?现在名称不仅无用,而且具有误导性!这个更好:

describe Array do
  it do
    Array.new.should be_empty
  end
end

RSpec还有一个非常巧妙的技巧:它会自动为你创建被测试类的实例,这样你就不必一遍又一遍地写"ClassUnderTest.new.should"了,只需要写"should"即可。
describe Array do
  it { should be_empty }
end

顺便说一句,就像开发人员可以弄清楚这是在测试什么一样,RSpec也可以。如果您要求它提供测试套件的可读摘要,无论哪种情况下它都会输出以下内容:
Array
 - should be empty

0

它们都做着同样的事情,如果不是这样,它们就有扩展点,这意味着你可以完成同样的事情。在这个意义上,你可以根据选择任何框架时使用的相同标准来评估它们(例如:流行度(NUnit),MS-Certiffied(MS-Test)等等)。

然而,如果你想要选择一个建议,我建议你阅读XUnit "why did we build xunit"页面,该页面指出了关于单元测试框架的某些问题。

如果你想看到所有框架之间的一些相似之处,你可以从here表格中看到,它们都有很多相似的特性,只是用不同的词来描述。

当然,选择BDD框架是另一回事。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接