在NUnit中我能做些什么在MSTest中无法做到吗?

时间:2009-09-28 15:42:21

标签: nunit mstest

在许多不同的论坛中已经以各种形式提出了这个问题,但是,恕我直言,我还没有找到一个真正得到明确回答的地方,所以我要重新构建它并再次问它

我在一家基本的微软商店工作。我们使用TFS,我们所有的开发人员都有MSDN订阅,包括VS的Team Suite版本。所以我们可以访问MSTest。

我已经阅读了各种NUnit与MSTest的比较,开发者社区似乎非常注重选择NUnit。但至少对我们的情况来说,给出的理由似乎并不是压倒性的或令人信服的。 (NUnit更新更频繁,NUnit更快,NUnit不需要TFS等。)

如果我选择的话,我可以使用NUnit,但是必须保护使用没有正式支持的开源软件。我需要一个相当令人信服的理由。

我基本上必须回答的是为了证明使用NUnit优先于MSTest是这样的:在NUnit中我能做些什么我在MSTest中无法做同样的努力吗?

12 个答案:

答案 0 :(得分:40)

  • NUnit包含一个[TestCase]属性,允许实现参数化测试。这在MSTest中不是现成的 - 它可以通过可扩展性来完成。
  • MsTest的ExpectedException属性有一个错误,即使错误,预期的消息永远不会被断言 - 测试将通过。
  • NUnit附带一个Assert.Throws API,允许在特定的代码行上测试异常而不是整个方法。 MSTest存在类似的功能(由为NUnit执行此操作的人员实现)但未随MSTest一起提供。
  • NUnit包含开箱即用的流畅版Assert API。 MSTest有第三方扩展,但没有MSTest附带。
  • NUnit允许抽象类成为测试装置(因此您可以继承测试装置)。 MsTest允许这样但将抽象类限制为单个程序集。
  • NUnit允许非公开类成为测试装置(截至最新版本)
  • NUnit是为单元测试的想法而单独创建的。 MSTest是为测试而创建的 - 还有一些单元测试。
  • NUnit包含PNunit(使用NUnit运行并行测试)。 MSTest在Visual Studio 2010中添加了此功能,可通过XML进行配置

答案 1 :(得分:24)

Roy,您的信息已经过时,特别是与2010年有关;

  
    

Nunit包含一个[TestCase]属性,允许实现参数化测试。这在MSTest中不存在

  

这可以使用2010年的单元测试可扩展性来实现。

  
    

MSTest的ExpectedException属性有一个错误,即使错误,预期的消息永远不会被断言 - 测试将通过。

  

纠正那仍然存在

  
    

NUnit有一个Assert.Throws API,允许在特定的代码行上测试异常而不是整个方法(你可以自己轻松地实现这个异常)

  
Jim在为NUnit做原始实现的同时为MSTest实现了一个版本的Assert.Throws,NUnit已经包含在后续版本中,MSTest还没有,但仍然可以使用它。

  
    

NUnit包含一个流畅的Assert API版本(如前所述 - Assert.That ..)

  

第三方为MSTest实施了其中几项

  
    

NUnit更快

  

看看杰米的评论他已经设法让MSTest跑得更快: - )

  
    

NUnit可以运行32位和64位测试(MSTest仅在32位IIRC中运行)

  

不是在2010年,内置了64位支持。

  
    

NUnit允许抽象类成为测试装置(因此您可以继承测试装置)。 MsTest没有。

  

这可以工作,但不能跨组件限制其有用性。

  
    

NUnit允许非公共类成为测试装置(截至最新版本)

  

还在那里

  
    

NUnit是为单元测试的想法而单独创建的。 MSTest是为测试而创建的 - 还有一些单元测试。

  

正确,有很多误解,MSTest与Nunit相同,但MSTest是一个通用框架。

  
    

NUnit包含PNunit(使用NUnit运行并行测试)。 MSTest仅在vs 2010中添加此功能

  

更正有一个XML配置设置,允许控制并行度。

答案 2 :(得分:8)

NUnit有richer assert API。 api特别优雅(流利,甚至),例如

Assert.That(Is.Unique, myResults);  // assert: myResults is a collection of unique items

如果你看过JUnit的Hamcrest扩展,你就会认出这种风格。

它也有不断增长的set of extensions,例如性能测试和excellent VS plugin

答案 3 :(得分:7)

我可以向您介绍几个关于MSTest挫折的博客:

公平地说,这些人正在尝试在非TFS构建服务器上设置MSTest。他们的一些问题不适用于您的情况。

我们主要是Microsoft商店,并使用TFS进行源代码管理。但是,我们使用TeamCity进行持续集成;我们喜欢它,它与TFS相当完美地集成在一起。我从未使用过MSTest;我们多年来一直在使用NUnit,并且没有理由改变。

MSTest应该与Team Suite紧密集成,因为(因为贵公司已经为此付出了巨额费用),这是一个有利于它的点。

NUnit的供应商锁定较少,并且具有丰富的API。正如serg10指出的那样,Assert.That语法特别强大和优雅。

最后,你可以编写好的单元测试而不需要所有的花哨功能。其中一些甚至可能妨碍(这是xUnit.net背后的理论)。我建议你的团队在一个测试框架上标准化;避免在MUnest和NUnit中的其他代码中使用一些代码。

我认为编写好的测试比选择框架更重要。考虑阅读The Art of Unit Testing: with Examples in .NET,编写一些测试,然后看看MSTest是否足以满足您团队的需求。

编辑:单元测试艺术的附录B对微软的单元测试框架有一些很好的评论。它提到YUnit作为扩展MSTest是多么繁琐的一个例子。但是,由于紧密集成,作者确实为团队系统用户建议了MSTest。

答案 4 :(得分:5)

我在MsTest和NUnit之间有一个很好的方式。 您可以使用MSTest框架来运行测试(每个测试的TestClass属性和TestMethod属性),但使用NUnit Assert API。

这样做:

using Microsoft.VisualStudio.TestTools.UnitTesting; 
using Assert = NUnit.Framework.Assert;  

现在你可以使用Assert.That(..)并且仍然有TFS自动构建和测试报告。 您的测试可以在VS,TestDriven.net或Resharper中运行,无关紧要,测试将失败或正确传递,失败输出将根据NUnit框架。

见这里: http://alsagile.com/archive/2010/03/09/stop-the-war-between-nunit-and-mstest-make-them.aspx

答案 5 :(得分:2)

  1. MSTest测试跑步者非确定性,这应该足以让您远离使用它。我无法使用集成的测试运行器从TFS 2010始终运行MSTest;它在项目构建和构建代理之间打破了一些不同的错误消息(并且不一致)。
  2. MSTest有时(不一致)因为泄漏内存而中断 - 即使使用最新版本的Visual Studio,我们仍会发生内存异常。这个问题的解决方法很糟糕。
  3. 我在MSTest上有其他一些小问题,并且在博客上写了一些关于使用MSTest的解决方法:http://www.pseale.com/blog/TFSAsYourBuildCIServerOnlyPositiveTakeaways1Of2.aspx
  4. 我发现这个问题是因为我将我们从MSTest切换到NUnit,因为我们不能再相信我们的CI构建的结果了,因为MSTest。切换到NUnit将允许我们(最终)相信CI构建失败是真实的,而不是另一个MSTest故障。这是真正的答案 - 只有NUnit(或其他非MSTest测试运行员)才能信任我们的CI构建

答案 6 :(得分:1)

我一直在为TestDriven.Net 3.0中的MSTest提供一流的支持。在以前的版本中,MSTest支持非常基础(似乎很少有人使用MSTest)。

从TestDriven.Net 3.0 Beta 2开始,对MSTest的所有单元测试相关属性提供了相当全面的支持。甚至支持使用DataSource属性的数据驱动测试。您的测试也将以接近NUnit的速度执行!

如果您使用MSTest,我很想知道在使用TestDriven.Net 3.0 Beta 2(或更高版本)执行时是否有任何单元测试失败。

请在您的MSTest项目上试一试,让我知道您是如何进行的: http://www.testdriven.net/download.aspx

注意,它不支持DeploymentItem或HostType属性。您可以使用“复制到输出目录”项目项设置而不是DeploymentItem。

答案 7 :(得分:1)

您可以更改NUnit中的代码,因为它是开源的。你不能用MSTest做到这一点。

答案 8 :(得分:1)

http://fluentassertions.codeplex.com。你可以做像

这样的事情
"ABCDEFGHI".Should().StartWith("AB").And.EndWith("HI").And.Contain("EF").And.HaveLength(9);

new[] { 1, 2, 3 }.Should().HaveCount(4, "because we thought we put three items in the 
collection"))

dtoCollection.Should().Contain(dto => dto.Id != null);

collection.Should().HaveCount(c => c >= 3);

dto.ShouldHave().AllPropertiesBut(d => d.Id).EqualTo(customer);

dt1.Should().BeWithin(TimeSpan.FromHours(50)).Before(dt2); 

Action action = () => recipe.AddIngredient("Milk", 100, Unit.Spoon);
action
   .ShouldThrow<RuleViolationException>()
   .WithMessage("Cannot change the unit of an existing ingredient")
   .And.Violations.Should().Contain(BusinessRule.CannotChangeIngredientQuanity

答案 9 :(得分:1)

@Dave Hanna MS Test是开箱即用的,所以不用担心部署和保持更新。 它还通过设计与Visual Studio和其他Microsoft产品集成。

流利的语法很好,但它不是功能差异,所以我忽略它。更不用说你可以使用扩展库在MS Test中拥有相同的功能。

性能。 99%的测试性能由被测系统控制,因此即使两个库之间100%的性能差异也会导致整体性能的差异。

开源与非开源:您从使用开源库中获益的机会很小。例外情况是当频繁地将更改拉入主干或者有足够的资源来保持修改的分支更新时。

答案 10 :(得分:1)

请仔细阅读ExpectedExceptionAttribute文档,没有说明测试异常消息,因此它不是未声明的错误。

第二个参数是断言消息,当未抛出预期的异常类型时显示的内容,而不是预期的异常消息。即像Assert.IsTrue中的第二个参数(条件,消息)。

答案 11 :(得分:0)

您可以使用Mono在Linux上轻松运行NUnit测试,我认为您不能通过MSTest测试来实现。