NUNIT使用详解(一)

2008/08/26 11:40

NUnit是一个单元测试框架,专门针对于.NET来写的,它是是xUnit的一员。NUnit完全由C#语言来编写,并且编写时充分利用了许多.NET的特性,比如反射,客户属性等等.
最重要的一点是它适合于所有.NET语言.

单元测试:
作为程序员在开发过程中,不可避免地要对软件的类及其方法进行测试。
在Web页面的测试过程中,好多朋友喜欢把测试结果使用Response.Write()显示在页面上。而在类库组件的开发时,由于没有可视化界面,有时不得不为该类库添模一个测试的项目(Console,WinForm,ASP.NET等),在该项目中调用类库组件的功能,以查看测试结果。
上面这种测试不是我们推荐的方法,因为我们在测试的时候应遵循以下原则:
    尽量不要破坏原有的代码结构,即不要在原代码中添加一些冗余的测试代码。
    测试模块应尽可能完整地展现测试结果。
    测试模块不应用完即扔掉,要保存以备后续的维护测试。
   
一、NUnit运行界面


《图1》
在右边有一个进度条,如果所有测试案例运行成功,就为绿色,反之如果有一个不成功,则为红色,但也有黄色的.
    绿色 描述目前所执行的测试都通过
    黄色 意味某些测试忽略,但是这里没有失败
    红色 表示有失败

左边的树状目录是我们们编写的每一个测试单元。

底部的状态条
   
状态:当所有测试完成时,状态变为Completed.运行测试中,状态是Running:
<test-name>
    Test Cases:说明加载的程序集中测试案例的总个数。这也是测试树里叶子节点的个数。
    Tests Run: 已经完成的测试个数。
    Failures: 到目前为止,所有测试中失败的个数.
    Time: 显示运行测试时间(以秒计)

二、在VS2008中配置NUnit进行测试
    1.新建一个类库项目。
    2.在解决方案中的项目图标上右击,选择“属性”。
    3.点击左边的“调试”标签
    4.在“启动操作”中选择“启动外部程序”,并指明NUnit程序的运行路径。
    5.在启动选项中的“工作目录”下,指明当前类库项目的DLL文件的所在路径。


    《图2》
    6.运行当前类库项目,我们会发现NUnit被启动起来了。

三、安装Unit与使用
   请到http://www.nunit.org/download.html下载NUnit,然后双击安装即可。
   
1.我们要使用NUnit对类库组件进行测试时,一般我们会新建一个测试类文件或新建一个测试项目。
    2.为测试项目添加引用“nunit.framework”
    3.在测试类文件中添加using NUnit.Framework;语句
    4.在该类文件或测试项目中编写测试代码,然后使用NUnit运行我们的测试代码以观察测试结果。

四、NUnit中的常用Attribute
所有NUnit属性都包含在Nunit.Framework命名空间里。测试项目必须引用框架的程序集,即nunit.framework.dll.

1.TestFixtureAttribute
    用来修饰测试类。这个属性标记一个类包含了测试方法。
    被TestFixtureAttribute修饰的类需满足以下限制
        a.必须是一个public类型,否则NUnit不会识别它。
        b.它必须有一个缺省的构造子,否则Nunit不能构建他。
        c.构造子不应该有任何方面的负面影响,因为在一个对话的过程中,NUnit可能构造类多次。

        如:
        using
System;
        using NUnit.Framework;
       [TestFixture]
        public class SuccessTests
        {
        // ...
        }

2.TestAttribute
   
用来修饰测试方法Test属性标记某个类的某个方法为一个测试方法,而且此类必需已经标记为一个TestFixture。
    一个测试方法的签名定义如下:
       
public void MethodName()
    注意:测试方法必须没有参数。如果程序员将测试方法标记为不正确的签名,它不会运行。
        如:
        using
System;
        using NUnit.Framework;
       [TestFixture]
        public class SuccessTests
        {
            [Test]
            public
void Add()
            {
               
//...
            }
        }

3.SetUpAttribute
   
用来修饰方法。所属的类必需已经标记为一个TestFixture。一个TestFixture可以仅有一个SetUp方法。如果有多个定义,TestFixture也会编译成功,但是测试不会运行。SetUpAttribute标记的方法是在每个测试方法被调用之前来完成的。
        如:
        using
System;
        using NUnit.Framework;
        [TestFixture]
        public class SuccessTests
        {
            [SetUp]

            public
void Init()
            { /* ...
*/ }

[TearDown]
            public
void Dispose()
            { /* ...
*/ }

   
[Test]

            public
void Add()
            { /* ...
*/ }
        }
   
SetUp属性是从任何基类继承而来。因此,如果基类已经定义了一个SetUp方法,那么这个方法会在每个派生的类的测试方法之前调用。如果你打算在派生类里加入更多的SetUp功能,你需要将方法标记为适当的属性,然后调用基类方法。(车延禄)

SetUpAttribute使用案例:
       
如:我们以测试加减法为例
        using
System;
        using NUnit.Framework;
        [TestFixture]
        public class NumersFixture
        {
                   
[Test]

                   
public void AddTwoNumbers()
                   
{
                               
int a=1;
                               
int b=2;
                               
int sum=a+b;
                               
Assert.AreEqual(sum,3);
                   
}
                  
[Test]

                   
public void MultiplyTwoNumbers()
                   
{
                               
int a = 1;
                               
int b = 2;
                               
int product = a * b;
                               
Assert.AreEqual(2, product);
                   
}
        }
        不难看出两个测试方法中有重复的代码,如何去除重复的代码呢?我们可以提取这些代码到一个独立的方法,然后标志这个方法为SetUp 属性,这样2个测试方法可以共享对操作数的初始化了,这里是改动后的代码:
        using
System;
        using NUnit.Framework;
        [TestFixture]
        public class NumersFixture
        {
                   
private int a;
                   
private int b;
                  
[SetUp]
                   
public void InitializeOperands()
                   
{
                               
a = 1;
                               
b = 2;

                   
}

  
[Test]
                   
public void AddTwoNumbers()
                   
{
                               
int sum=a+b;
                               
Assert.AreEqual(sum,3);
                   
}
                   
[Test]
                   
public void MultiplyTwoNumbers()
                   
{
                               
int product = a * b;
                               
Assert.AreEqual(2, product);
                   
}
        }
       
这样NUnit将在执行每个测试前执行标记SetUp属性的方法.在本例中就是执行InitializeOperands()方法.记住,这里这个方法必须为public,不然就会有以下错误:Invalid Setup or TearDown
method signature

4.TearDownAttribute
   用来修饰方法所属的类必需已经标记为一个TestFixture。一个TestFixture可以仅有一个TearDown方法。如果有多个定义,TestFixture也会编译成功,但是测试不会运行。被TearDownAttribute修饰的方法是每个测试方法被调用之后来执行的。
        如:
        using
System;
        using NUnit.Framework;
        [TestFixture]
        public class SuccessTests
        {
            [SetUp]
            public
void Init()
            { /* ...
*/ }


[TearDown]
            public
void Dispose()
            { /* ...
*/ }

  
[Test]
            public
void Add()
            { /* ...
*/ }
        }
   
TearDown属性是从任何的基类继承而来。因此,如果基类已经定义了一个TearDown方法,那么这个方法会在每个派生的类的测试方法之后调用。如果你打算在派生类里加入更多的TearDown功能,你需要将方法标记为适当的属性,然后调用基类方法。

5.TestFixtureSetUpAttribute
   用来修饰方法。所属的类必需已经标记为一个TestFixture。这些个属性标记的方式在fixture任何测试执行之前完成。TestFixture可以仅有一个TestFixtureSetUp方法。如果定义了多个,TestFixture可以成功编译,但是测试不会被执行。

6.TestFixtureTearDownAttribute
   用来修饰方法。所属的类必需已经标记为一个TestFixture。这些个属性标记的方式在fixture任何测试执行之后完成。TestFixture可以仅有一个TestFixtureTearDownAttribute方法。如果定义了多个,TestFixture可以成功编译,但是测试不会被执行。
        如:
        namespace
NUnit.Tests
        {
          using System;
          using NUnit.Framework;


[TestFixture]
          public class
SuccessTests
          {
          
[TestFixtureSetUp]
            public
void Init()
            { /* ...
*/ }


[TestFixtureTearDown]

            public
void Dispose()
            { /* ...
*/ }

[Test]
            public
void Add()
            { /* ...
*/ }
          }
        }

SetUp/TearDown方法提供达到测试隔离性的目的.SetUp确保共享的资源在每个测试运行前正确初始化,TearDown确保没有运行测试产生的遗留副作用. TestFixtureSetUp/TestFixtureTearDown同样提供相同的目的,但是却在test fixture范围里
   
我们写一个简单的测试来说明什么方法调用了,怎么合适调用
        using
System;
        using NUnit.Framework;
        [TestFixture]
        public class
LifeCycleContractFixture
        {
            [TestFixtureSetUp]

            public
void FixtureSetUp()
            {
               
Console.Out.WriteLine("FixtureSetUp");
            }
           
[TestFixtureTearDown]
            public
void FixtureTearDown()
            {
               
Console.Out.WriteLine("FixtureTearDown");
            }
            [SetUp]
            public
void SetUp()
            {
               
Console.Out.WriteLine("SetUp");
            }
            [TearDown]
            public
void TearDown()
            {
               
Console.Out.WriteLine("TearDown");
            }
           [Test]
            public
void Test1()
            {
               
Console.Out.WriteLine("Test 1");
            }
            [Test]
            public
void Test2()
            {
               
Console.Out.WriteLine("Test 2");
            }
        }
        运行结果:
        FixtureSetUp
        SetUp
        Test 1
        TearDown
        SetUp
        Test 2
        TearDown
        FixtureTearDown
   
7.ExpectedExceptionAttribute
   修饰方法,用来测试一个方法是否抛出了指定的异常。本属性有两种重载方式。第一种是一个Type,此Type为期望的异常的精确类型。 第二种是一个期望的异常全名的字符串。(车延禄)
    在执行测试时,如果它抛出了指定的异常,那么测试通过。如果抛出一个不同的异常,测试就失败。如果抛出了一个由期望异常继承而来的异常,这也是成功的。
        using
System;
        using NUnit.Framework;
        [TestFixture]
        public class SuccessTests
        {
           [Test]
           
[ExpectedException(typeof(InvalidOperationException))]
            public
void ExpectAnExceptionByType()
            { /* ...
*/ }


[Test]
           
[ExpectedException("System.InvalidOperationException")]
            public
void ExpectAnExceptionByName()
            { /* ...
*/ }
        }
       
8.CategoryAttribute
    修饰方法或修饰类。用来把测试分组,可以使用NUnit的Categories选项卡选择要测试的组,或排除一些组。
   
对类分组:
        using
System;
        using NUnit.Framework;
        [TestFixture]
       
[Category("LongRunning")]
        public class LongRunningTests
        {
        // ...
        }
    对方法分组:
        using
System;
        using NUnit.Framework;
        [TestFixture]
        public class SuccessTests
        {
            [Test]
           
[Category("Long")]
            public
void VeryLongTest()
            { /* ...
*/ }
        }

下面我们编写三个测试方法,并分为两组“Compare”和“TestNull”,在NUnit中测试“Compare”组的内容:
    第一步:点击左侧的“Categories”选项卡
    第二步:在“Available Categories”列表框中选择“Compare”,点击“Add”按钮
    第三步:点击左侧“Test”选项卡,点击树状目录中的“Class1”,点击“Run”按钮
   
我们发现只有TestTowInstanceName和TestTowInstanceEqual两个测试方法运行了,而TestNull没有运行,因此TestNull不是“Compare”组的。


《图3》


《图4》

9.ExplicitAttribute
    用来修饰类或方法。Explicit属性会忽略一个测试或测试Fixture,直到它被显式的选择运行。。如果test和test fixture在执行的过程中被发现,就忽略他们。所以,这样一来进度条显示为黄色,因为有test或test fixture忽略了。
    修饰类:
        using
System;
        using NUnit.Framework;
        [TestFixture, Explicit]
        public class ExplicitTests
        {
        // ...
        }
    修饰方法:
        using
System;
        using NUnit.Framework;

   
[TestFixture]

        public class SuccessTests
        {
            [Test,
Explicit]
            public
void ExplicitTest()
            { /* ...
*/ }
        }
   

10.IgnoreAttribute
   用来修饰类或方法。由于种种原因,有一些测试我们不想运行.当然,这些原因可能包括你认为这个测试还没有完成,这个测试正在重构之中,这个测试的需求不是太明确.但你有不想破坏测试,不然进度条可是红色的哟.怎么办?使用Ignore属性.你可以保持测试,但又不运行它们。
    这个特性用来暂时不运行一个测试或fixture。比起注释掉测试或重命名方法,这是一个比较好的机制,因为测试会和余下的代码一起编译,而且在运行时有一个不会运行测试的标记,这样保证不会忘记测试。
    修饰类:
        using
System;
        using NUnit.Framework;
        [TestFixture]
        [Ignore("Ignore a
fixture")]
        public class SuccessTests
        {
        // ...
        }

修饰方法
        using
System;
        using NUnit.Framework;

[TestFixture]
        public class SuccessTests
        {
            [Test]
           
[Ignore("Ignore a test")]
            public
void IgnoredTest()
            { /* ...
*/ }
        }

出处:http://wenku.baidu.com/view/c40f6f53c281e53a5802ffa8.html

N​Unit的Attribute​使​用​详​解的更多相关文章

  1. JavaScript 中 Property 和 Attribute 的区别详解

    property 和 attribute非常容易混淆,两个单词的中文翻译也都非常相近(property:属性,attribute:特性),但实际上,二者是不同的东西,属于不同的范畴. property ...

  2. 测试框架unit之assertion断言使用详解

    NUnit是.Net平台的测试框架,广泛用于.Net平台的单元测试和回归测试中,下面我们用示例详细学习一下他的使用方法 任何xUnit工具都使用断言进行条件的判断,NUnit自然也不例外,与其它的xU ...

  3. ASP.NET MVC5 新特性:Attribute路由使用详解 (转载)

    1.什么是Attribute路由?怎么样启用Attribute路由? 微软在 ASP.NET MVC5 中引入了一种新型路由:Attribute路由,顾名思义,Attribute路由是通过Attrib ...

  4. Systemd Unit文件中PrivateTmp字段详解-Jason.Zhi

    如下图,在开发调试的时候会遇到这么一个问题. file_put_contents时,$tmp_file显示的目标文件是/tmp/xxx.而这个文件实际放在linux的目录却是/tmp/systemd- ...

  5. ASP.NET MVC5 新特性:Attribute路由使用详解

    1.什么是Attribute路由?怎么样启用Attribute路由? 微软在 ASP.NET MVC5 中引入了一种新型路由:Attribute路由,顾名思义,Attribute路由是通过Attrib ...

  6. ASP.NET MVC5 :Attribute路由使用详解

    1.什么是Attribute路由?怎么样启用Attribute路由? 微软在 ASP.NET MVC5 中引入了一种新型路由:Attribute路由,顾名思义,Attribute路由是通过Attrib ...

  7. C++中const用法详解

    本文主要内容来自CSDN论坛: http://bbs.csdn.net/topics/310007610 我做了下面几点补充. 补充: 1. 用const声明全局变量时, 该变量仅在本文件内可见, 类 ...

  8. .Net Attribute详解(下) - 使用Attribute武装枚举类型

    接上文.Net Attribute详解(上)-Attribute本质以及一个简单示例,这篇文章介绍一个非常实用的例子,相信你一定能够用到你正在开发的项目中.枚举类型被常常用到项目中,如果要使用枚举To ...

  9. .Net Attribute详解(一)

    .Net Attribute详解(一) 2013-11-27 08:10 by JustRun, 1427 阅读, 14 评论, 收藏, 编辑 Attribute的直接翻译是属性,这和Property ...

随机推荐

  1. wkhtmtopdf--高分辨率HTML转PDF(三)

    代码篇 浏览了很多实例,总找不到既能把HTML保存为PDF,同时实现流抛出的,所以自己琢磨了许久,终于实现了这样两个需求的结合体,下面来贡献一下吧~~ 下面我们来选择一个网页打印下,保存为PDF,而且 ...

  2. 常用技巧之JS判断数组中某元素出现次数

    先上代码:function arrCheck(arr){  var newArr = [];  for(var i=0;i<arr.length;i++){    var temp=arr[i] ...

  3. zoj3696Alien's Organ (二项分布,泊松分布求近似值)

    /*二项分布即重复n次的伯努利试验,每次发生的概率一样,假设成功的概率是p,那么失败的概率就是1-p: 二项分布的概率公式:试验中发生K次的概率是 P(ξ=K)= C(n,k) * p^k * (1- ...

  4. foo、bar美国版的张三李四

    不管看javascript还是其他语言举例,经常看到使用foo和bar来充当变量.那么究竟foo.bar是什么鬼? 一说:foo 和 bar 组合在一起所构成的 foobar 应该最能反映其原始的意思 ...

  5. Sybase中的load table的用法

    Sybase中的load table的用法 用sybase iq作为数据仓库的存储,确实有其独特的特点和优势,但是在数据ETL的时候,如果用insert.update方式,速度太慢,大概是2秒钟左右一 ...

  6. 20145104张家明 《Java程序设计》第3周学习总结

    20145104张家明 <Java程序设计>第4周学习总结 教材学习内容总结 第四章 认识对象 4.1 类与对象 4.1.1 定义类 类定义时使用class关键词,建立实例要用new关键词 ...

  7. 「翻译」一篇redis文章引发的翻译——JVM能支持多少线程?

    昨天看了一篇关于redis 的文章https://www.cnblogs.com/fanwencong/p/5782860.html 作者说他模拟了100万线程的并发,我对这个有一些怀疑,看了评论也有 ...

  8. ubuntu 18.04 64bit build tensorflow report error:C++ compilation of rule '//tensorflow/core/kernels:broadcast_to_op' failed (Exit 4)

    注意:笔者未能在Ubuntu18.04 64bit下成功从源码编译cpu版本的tensorflow Ans: 1.You are likely running out of memory. Try r ...

  9. Java知识弥补-Android开发

    目录 数据结构 1. Map-HashMap 2. StringBuilder 3. List-ArrayList 4. Vector 5. Stack 6. Set 由于这学期开了android课程 ...

  10. JavaScript权威指南--正则表达式

    知识要点 正则表达式,是一个描述字符模式的对象.javascript的RegExp类表示正则表达式,String和RegExp都定义了方法,后者使用正则表达式进行强大的模式匹配和文本检索与替换功能. ...