我已经阅读了很多关于可用的.NET单元测试框架的内容。我不清楚的是,区分可用框架的关键特性是什么。在评估单元测试框架时,您需要具备哪些必备功能?
答案 0 :(得分:2)
以下是我要寻找的一些事情
Assert.Throws
捕获的异常吗?断言是否能够使用指定的容差进行数值比较?答案 1 :(得分:2)
我寻找的是工具集支持,我的特别优先事项是持续集成支持。单元测试中最重要的部分(至少对我而言,不是TDD的忠实粉丝)是将它们插入我的CI构建服务器。
出于这个原因,我赞成nUnit,因为在CruiseControl中有预先构建的构建任务,这是我选择的构建服务器。这并不是说你不能将任何其他测试框架插入CC,nUnit恰好是一个容易使用的。
对于可用的功能,当您使用价格极高的Visual Studio Team System并在后端运行TFS时,MSTest有一些非常好的附加组件。
说完所有这些之后,各个测试框架的功能确实没有那么大差异(我有使用xUnit,nUnit和MSTest的经验) - 它们都允许你定义单元测试,并报告如何mnay通过了多少次失败。它们都有某种GUI,可以将它们全部集成到构建服务器中。
答案 2 :(得分:1)
我同意它们在断言和其他基本功能方面都非常相似。它们开始存在差异的地方是更高级的选项,例如脚本框架,构建工具,自动集成等。
如果您打算使用CruiseControl.NET等大量自定义构建选项和自定义scritpting来运行高度自动化的构建过程,我可能会使用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
---------------------------------------------------------------------------------
答案 3 :(得分:0)
他们都做了很多相同的事情,如果他们不这样做,他们有扩展点,这意味着你可以完成同样的事情。从这个意义上讲,您可以根据您在选择任何框架时使用的相同标准(例如人气(NUnit),MS-Certiffied(MS-Test)等)来评估它们。
但是,如果您需要有关选择的建议,我建议您阅读XUnit "why did we build xunit"页面,其中指出了与单元测试框架有关的某些问题。
如果你想看到所有框架之间的一些相似之处,你可以从表here中看到,它们都有很多类似的功能,只是不同的单词。
当然,选择BDD框架是一种不同的鱼。
答案 4 :(得分:0)
我在每个测试框架中遗漏的一件事是统一断言,我的意思是,无论我断言什么,测试都应该看起来一样。我是否对值进行基于状态的断言,对模拟执行基于行为的断言或断言应该抛出异常。
我将使用Ruby作为示例,但这适用于任何环境。 (而且,顺便说一句,你不仅限于测试.NET应用程序的C#框架,你可以使用任何 .NET语言,其中Ruby当然是其中之一,Python,Scheme,F#,...... )
这是test/unit
(JUnit早期版本的一个端口),Mocha用于模拟。
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
注意所有断言看起来不同并且位于不同的位置,实际的测试代码也在三个不同的位置。
这就是期望,AFAIK是唯一能够做到正确的框架。 (实际上,它是专门为了统一断言而创建的。)不幸的是,由于作者不再从事任何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,肯定会越来越接近。
答案 5 :(得分: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
,你可以说{ {1}}:
should
而且,BTW,就像开发人员可以弄清楚这是在测试什么,RSpec也是如此。如果您要求客户可读的测试套件摘要,这就是它在所有三种情况下都会吐出的内容:
describe Array do
it { should be_empty }
end