一、单元测试框架的选择

在选择单元测试框架时,可以从以下几个方面去考虑:

  • 支持自动检测注册用例:框架能否支持简单地构造用例并自动注册测试用例到测试框架中;
  • 支持测试Fixture:即是否支持为一组测试用例建立统一的脚手架,方便测试用例的上下文构造;
  • 强大的断言系统:是否提供强大的断言系统,供使用者在用例中描述期望;
  • 灵活的Test Suite定义:可以支持灵活的对测试用例分组;
  • 测试能力:是否支持异常测试以及参数测试;
  • 测试filter定义:可以支持灵活的命令行参数,对运行用例进行分组和过滤;
  • 测试结果及报表生成:是否可以生成易于阅读的测试结果报告以及报表文件;
  • 用例依赖管理:是否支持编辑用例的依赖关系,让用例之间互相组合,但是又不破坏每个用例的独立性;
  • 沙盒模式:是否支持测试用例的沙盒模式,降低每个测试用例上下文清理的工作;
  • 是否开源:包括公开的文档和社区的支持是否全面;

常用的C#单元测试框架有xUnit.Net, NUnit, MSTest(Visual Studio),以下主要介绍NUnit测试框架。

二、NUnit测试框架简介

NUnit是一个开源的单元测试框架,用于.NET framework和Mono框架下进行的单元测试。与JUnit在Java中的作用相同,是xUnit家族中的一员。

三、NUnit测试框架安装(Visual Studio)

NUnit框架安装有以下几种方式:

  1. NUnit完整版安装(通过NuGet)
  2. NUnitLite安装(通过NuGet)
  3. 下载Zip和/或MSI文件
  4. 结合的方法

以下介绍前两种安装方法:

1. NUnit完整版安装(通过NuGet)

  1. 在Visual Studio界面,工具 -> NuGet包管理器 -> 管理解决方案的NuGet程序包;

  2. 找到并选择NUnit包,在右侧勾选要添加的项目(测试项目,通常为dll),点击安装。Visual Studio会将包下载到解决方案所在目录的packages文件夹下,并在勾选的项目中引用NUNit framework;

  3. NUnit单元测试可以使用NUnit框架自带的runner运行,也可以集成到Visual Studio的测试平台上,使用Microsoft提供的的runner运行。这两种方式需要安装不同的NuGet包:

    使用NUnit框架自带的runner:在NuGet包管理器中搜索NUnit.Console,并安装。安装完之后,就可以在packages\NUnit.ConsoleRunner.3.X.X\tools中找到unit3-console并运行;

    使用Microsoft提供的的runner:在NuGet包管理器中搜索NUnit3TestAdapter,并安装;

  4. 确认测试项目引用了nunit.framework。

2. NUnitLite安装(通过NuGet)

NUnitLite是一种轻量化的安装方式,不用安装NUnit runner和test engine assemblies。仅需要安装NUnit framework和一个小型的runner即可。

  1. 创建一个控制台程序项目作为测试项目;
  2. 与NUnit完整版安装类似,在NuGet包管理器中搜索并安装NUnit和NUnitLite;
  3. 安装完之后,确认测试项目引用了nunit.framework和nunitlite;
  4. 一个"Program.cs"的文件会被拷贝到测试项目中,里面包括一个程序入口函数Main(),如果测试项目中已存在Main()函数,可以删掉这个文件,但是需要按照下面的格式配置Main()函数,来启动nunitlite runner;
public static int Main(string[] args)
{return new AutoRun().Execute(args);
}
  1. 写好测试用例后,启动测试项目就可以了。

四、NUnit框架常用Attributes

[TestFixture]
标识一个测试类

[Test]
标识一个测试方法(对于非参数化的测试,为一个测试用例)

[TestFixture]
public class SuccessTests
{// A simple test[Test]public void Add(){ /* ... */ }
}

[TestCase]
在参数化测试中,标识一个测试用例(可以包含输入和预期数据)

[TestCase(12, 3, 4)]
[TestCase(12, 2, 6)]
[TestCase(12, 4, 3)]
public void DivideTest(int n, int d, int q)
{Assert.AreEqual(q, n / d);
}
[TestCase(12, 3, ExpectedResult=4)]
[TestCase(12, 2, ExpectedResult=6)]
[TestCase(12, 4, ExpectedResult=3)]
public int DivideTest(int n, int d)
{return n / d;
}

[TestCaseSource]
在参数化测试中,标识一个测试用例的参数来源

public class MyTestClass
{[TestCaseSource(nameof(DivideCases))]public void DivideTest(int n, int d, int q){Assert.AreEqual(q, n / d);}static object[] DivideCases ={new object[] { 12, 3, 4 },new object[] { 12, 2, 6 },new object[] { 12, 4, 3 }};
}
public class MyTestClass
{[TestCaseSource(typeof(DivideCases))]public void DivideTest(int n, int d, int q){Assert.AreEqual(q, n / d);}
}class DivideCases : IEnumerable
{public IEnumerator GetEnumerator(){yield return new object[] { 12, 3, 4 };yield return new object[] { 12, 2, 6 };yield return new object[] { 12, 4, 3 };}
}

[TestFixtureSource]
在参数化测试中,为一个测试脚手架设置参数来源,通过构造函数的参数传递

[TestFixtureSource(nameof(FixtureArgs))]
public class MyTestClass
{public MyTestClass(string word, int num) { ... }/* ... */static object [] FixtureArgs = {new object[] { "Question", 1 },new object[] { "Answer", 42 }};
}

[Setup]
在一个TestFixture中,提供运行测试用例之前的统一设置,每次运行一个测试用例之前就会调用一次。

[TearDown]
在一个TestFixture中,提供运行测试用例之后的统一操作,每次运行一个测试用例之后就会调用一次。

namespace NUnit.Tests
{using System;using NUnit.Framework;[TestFixture]public class SuccessTests{[SetUp] public void Init(){ /* ... */ }[TearDown] public void Cleanup(){ /* ... */ }[Test] public void Add(){ /* ... */ }}
}

[OneTimeSetUp]
在一个TestFixture中,提供运行测试用例之前的统一设置,运行TestFixture中任意一个测试用例之前会调用一次。

[OneTimeTearDown]
在一个TestFixture中,提供运行测试用例之后的统一操作,运行TestFixture中任意一个测试用例之后会调用一次。

[Ignore]
标识一个测试类或方法由于某些原因不应执行,在NUnit3框架中,必须指明原因。

namespace NUnit.Tests
{using System;using NUnit.Framework;[TestFixture][Ignore("Ignore a fixture")]public class SuccessTests{// ...}
}

五、NUnit框架的断言系统

NUnit使用两种断言系统,约束模型(Constraint Model)和经典模型(Classic Model)。

经典模型

经典模型对于每一种断言都有单独的一个方法,例如:

StringAssert.AreEqualIgnoringCase("Hello", myString);

Assert类提供一些非常常用的断言方法:

Assert.True
Assert.False
Assert.Null
Assert.NotNull
Assert.Zero
Assert.NotZero
Assert.IsNaN
Assert.IsEmpty
Assert.IsNotEmpty
Assert.AreEqual
Assert.AreNotEqual
Assert.AreSame
Assert.AreNotSame
Assert.Contains
Assert.Greater
Assert.GreaterOrEqual
Assert.Less
Assert.LessOrEqual

除此之外还有以下几个类也提供相应的断言方法:

  • String Assert
  • Collection Assert
  • File Assert
  • Directory Assert

约束模型

约束模型只有Assert.That()一种方法,参数是约束对象。根据不同的断言类型有不同的约束对象,形成一系列重载函数。以下两个断言形式是等价的:

Assert.That(myString, Is.EqualTo("Hello"));
Assert.That(myString, new EqualConstraint("Hello"));

目前NUnit框架仍然支持旧的经典模型,但是已不添加新功能,新功能都是使用约束模型实现的。因此应尽可能的使用约束模型。有些断言形式只能使用约束模型,如:

int[] array = new int[] { 1, 2, 3 };
Assert.That(array, Has.Exactly(1).EqualTo(3));
Assert.That(array, Has.Exactly(2).GreaterThan(1));
Assert.That(array, Has.Exactly(3).LessThan(100));

而本质上经典模型全部是使用约束模型实现的,也就是说所有的经典模型的断言形式都能找到对应的约束模型的形式,比如以下两个断言是等价的:

Assert.AreEqual(4, 2+2);
Assert.That(2+2, Is.EqualTo(4));

多个断言(multiple asserts)

一般来说如果一个函数包含多个断言,一个断言失败了,后续的断言(如果有的话)不会执行,因此,一般一个测试仅会有一个断言。但是某些情况,比如一个UI界面样式的测试可能需要在一个测试方法里添加多个断言,此时可以使用Assert.Multiple方法:

[Test]
public void ComplexNumberTest()
{ComplexNumber result = SomeCalculation();Assert.Multiple(() =>{Assert.AreEqual(5.2, result.RealPart, "Real part");Assert.AreEqual(3.9, result.ImaginaryPart, "Imaginary part");});
}

此时,如果代码块中的第一个断言失败了,测试不会马上终止,而是继续执行第二个断言,最终将结果统一返回。

参考:

  1. NUnit官网.
  2. C/C++怎么做好单元测试.

单元测试及NUnit测试框架简介(二)相关推荐

  1. Pytest测试框架(二):pytest 的setup/teardown方法

    系列文章目录 Pytest测试框架(一):pytest安装及用例执行 Pytest测试框架(二):pytest 的setup/teardown方法 Pytest测试框架(三):pytest fixtu ...

  2. 模糊测试之SPIKE测试框架简介

    模糊测试简介 模糊测试概述 模糊测试(Fuzzing),是一种通过向目标系统提供非预期的输入并监视异常结果来发现软件漏洞的方法.其核心思想是自动或半自动的生成随机数据输入到一个程序中,并监控目标程序异 ...

  3. python测试4_Python 各种测试框架简介(四):pytest

    pytest 有时也被称为 py.test,是因为它使用的执行命令是 $ py.test.本文中我们使用 pytest 指代这个测试框架,py.test 特指运行命令. ##较于 nose 这里没有使 ...

  4. Python 各种测试框架简介(三):nose

    摘要 这里将从( pythontesting.net)陆续编译四篇 Python 测试框架的简介,分别为:doctest.unittest.nose 和 pytest.本篇为第三篇:nose 本篇将介 ...

  5. Metasploit渗透测试框架简介

    Metasploit渗透测试框架介绍 Metasploit是一个免费的.可下载的框架,通过它可以很容易地获取.开发并对计算机软件漏洞实施攻击.它本身附带数百个已知软件漏洞的专业级漏洞攻击工具.当H.D ...

  6. 单元测试 : Googel test测试框架

    1.什么是gtest gtest是一个跨平台的(Liunx.Mac OS X.Windows .Cygwin .Windows CE and Symbian ) C++单元测试框架,由google公司 ...

  7. unittest测试框架简介

    一.前言: python自动化测试框架种,比如:unittest,pytest,robotframework等.单元测试框架就两个unittest,pytest.其中unittest是python自带 ...

  8. allure 测试报告本地打开_Pytest和Allure测试框架(二)

    七, 单元自动化测试pytest和allure在测试中应用 自动执行 1, 单元测试测试报告展示 2, conftest中编写driver,范围session,使用 addfinalizer在测试结束 ...

  9. 自动化测试--实现一套完全解耦的简单测试框架(二)

    一:每次运行都需要打开代码工具,如eclipse或者IDE等.为了后面的持续集成,直接使用Maven命令去运行自动化测试,需要引入surfire插件.笔者使用的是2.10版本Surefire和6.9. ...

最新文章

  1. star ccm+ 用户指南_star-ccm边界层处理方法
  2. gtid mysql failover_Keepalived + MySQLfailover + GTIDs 高可用
  3. QT小例子 ---文件查找
  4. js鼠标移动到指定位置_Python: pyautogui模块之鼠标控制
  5. 微信小程序实现循环列表下拉功能(点击事件)
  6. defer和async的原理与区别
  7. hypixel服务器免费低延迟ip,国服hypixel服务器ip
  8. LINUX REDHAT第九单元文档
  9. linux 3.2.0 卸载,linux python3编译以及 卸载,python默认为python3 ,pip默认为pip3,亲测版...
  10. 把collections.Counter的计数结果转为pandas的DataFrame
  11. 滴滴工程师带你深入理解 HTTP通信细节
  12. 小程序随笔(关于香港手机号无法接收短信)
  13. window热敏打印机驱动安装
  14. Python金融系列第五篇:多元线性回归和残差分析
  15. Unity 六边形地图系列(一) 【笔记】: 创建一个六边形网格
  16. 2021十大手表品牌TOP排行榜
  17. 百度云网盘资源高速下载免登录网页版教程分享
  18. 学习JAVABEANS
  19. Jasperserver 添加字体方法
  20. #175-【线段树与树状数组】砍树

热门文章

  1. C++引用的超详细解释及误区纠正,不看后悔哦(中)
  2. 图片怎么批量转二维码?多张图片如何实现一图一码?
  3. 创建角色和ansible-galaxy简单实用
  4. D-Tale:一款功能异常强大的探索性数据分析工具
  5. 实现一款简单的音乐播放器
  6. Excel如何快速将多列转为排成一列
  7. 车载SOA软件架构:建模语言(SoaML)
  8. win10安装anaconda详细教程
  9. Floodlight 入门 之 起步篇 - 建立一个Floodlight模块
  10. 什么是物联网操作系统?