C# 单元测试全解析

目录
  • 1、前言
  • 2、单元测试
    • 2.1 单元测试的定义
    • 2.2 单元测试的好处
    • 2.3 单元测试的原则
  • 3、.NET 中的测试框架
    • 3.1 MS Test
    • 3.2 NUnit
    • 3.3 XUnit
  • 4、XUnit 的基本使用
  • 5、其他

1、前言

“不会写单元测试的程序员不是合格的程序员,不写单元测试的程序员不是优秀的工程师。”

那么问题来了,什么是单元测试,如何做单元测试。

2、单元测试

2.1 单元测试的定义

按照维基百科上的说法,单元测试(Unit Testing)又称为模块测试, 是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在面向对象编程中,最小单元就是方法,包括基类、抽象类、或者派生类(子类)中的方法。按照通俗的理解,一个单元测试判断某个特定场条件下某个特定方法的行为,如斐波那契数列算法,冒泡排序算法。

单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义, 如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。

—— 百度百科

2.2 单元测试的好处

  • 它是一种验证行为。程序中的每一项功能都是测试来验证它的正确性。
  • 它是一种设计行为。编写单元测试将使我们从调用者观察、思考。特别是先写测试(test-first),迫使我们把程序设计成易于调用和可测试的,有利于程序的解耦和模块化。
  • 它是一种编写文档的行为。单元测试是一种无价的文档,它是展示函数或类如何使用的最佳文档。这份文档是可编译、可运行的,并且它保持最新,永远与代码同步。
  • 它具有回归性。自动化的单元测试避免了代码出现回归,编写完成之后,可以随时随地的快速运行测试。
  • 高效。自动化的单元测试节省了开发上调试BUG的时间,绝大多数BUG可以通过单元测试测试出来,并且可以减少测试人员的测试时间。有时候通过写单元测试能够更好的完善自己程序的逻辑,让程序变得更加美好。

2.3 单元测试的原则

  • 可重复运行的
  • 持续长期有效,并且返回一致的结果
  • 在内存中运行,没有外部依赖组件(比如说真实的数据库,真实的文件存储等)
  • 快速返回结果
  • 一个测试方法只测试一个问题

3、.NET 中的测试框架

现在比较流行的测试框架包括微软的 MS Test(VS Test)NUnitXUnit

3.1 MS Test

VS单元测试的主要类:Assert、StringAssert、CollectionAssert,具体可参照 MSDN介绍

有些时候我们需要对测试的方法用到的数据或配置进行初始化,有几个特殊的测试方法。

如果需要针对测试中的所有虚拟用户迭代仅执行一次初始化操作,请使用 TestInitializeAttribute

初始化方法的运行顺序如下:

  1. AssemblyInitializeAttribute 标记的方法。
  2. ClassInitializeAttribute 特性标记的方法。
  3. TestInitializeAttribute 特性标记的方法。
  4. TestMethodAttribute 特性标记的方法。

使用 VS Test 的时候,首先我们需要标记测试方法所在类 TestClass,测试方法标记为 TestMethod

3.2 NUnit

NUnit 测试框架使用方法与 MS Test 类似

有一些是 NUnit 中的,但是MS Test框架中是没有的:

Assert.IsNaN/Assert.IsEmpty/Assert.IsNotEmpty/Assert.Greater/Assert.GreaterOrEqual

想要同时使用 VS Test 和 NUnit 的话可以使用宏来区分不同的测试框架,例如:

#if !NUNIT
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using Category = Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute;
#else
	using NUnit.Framework;
	using TestClass = NUnit.Framework.TestFixtureAttribute;
	using TestMethod = NUnit.Framework.TestAttribute;
	using TestInitialize = NUnit.Framework.SetUpAttribute;
	using TestCleanup = NUnit.Framework.TearDownAttribute;
	using TestContext = System.Object;
	using ClassCleanup = NUnit.Framework.TestFixtureTearDownAttribute;
	using ClassInitialize = NUnit.Framework.TestFixtureSetUpAttribute;
#endif

从上面可以看得出来 nunit 很多东西和 vs test 是很类似的,声明测试类,测试方法,初始化方法等

3.3 XUnit

XUnit 是另一个测试框架,个人觉得 XUnit 测试更加简洁一些,初始化和释放资源不需要标记单独的方法,初始化直接放在构造方法里,资源释放实现 IDisposable 接口,在 Dispose 方法中进行测试的清理工作即可,相比 ms test(vs test)和 NUnit,我觉得 Xunit 更方便一些,并且对于 Assert ,xunit 更简洁,例如:在 ms test 中的 Assert.IsNull(null);/Assert.IsTrue(1 == 1); 在 xunit 中则是 Assert.Null(null);/Assert.True(1 == 1);,虽然看上去差不多,但是写的多了就会觉得 xunit 更简洁一些。

xunit 不需要对测试方法所在类型标记 TestClass ,只需要在测试方法上标记 Fact 或者使用数据驱动的 Theory

4、XUnit 的基本使用

使用 XUnit 来写测试方法可以使得测试代码更为简洁,更加简单,推荐使用 xunit 来测试自己的代码

测试示例:

public class ResultModelTest
{
    [Fact]
    public void SuccessTest()
    {
        var result = ResultModel.Success();
        Assert.Null(result.ErrorMsg);
        Assert.Equal(ResultStatus.Success, result.Status);
    }

    [Theory]
    [InlineData(ResultStatus.Unauthorized)]
    [InlineData(ResultStatus.NoPermission)]
    [InlineData(ResultStatus.RequestError)]
    [InlineData(ResultStatus.NotImplemented)]
    [InlineData(ResultStatus.ResourceNotFound)]
    [InlineData(ResultStatus.RequestTimeout)]
    public void FailTest(ResultStatus resultStatus)
    {
        var result = ResultModel.Fail("test error", resultStatus);
        Assert.Equal(resultStatus, result.Status);
    }
}

最基本的测试,使用 Fact 标记测试方法,使用 Assert 来断言自己对结果的预期

可以使用 Theory 来自己指定一批数据来进行测试,来实现测试数据驱动测试,简单的数据可以通过 InlineData 直接指定,也可以使用 MemberData 来指定一个方法来返回用于测试的数据,也可以自定义一个继承于 DataAttributeData Provider

5、其他

在我们开发过程中测试是非常重要的一部分,高质量项目的一个重要指标就是测试覆盖率,一个高质量的开源项目一定是有比较完善的测试项目的,所以对于测试非常有必要了解一下,并将它集成到自己的项目中持续保证项目的高质量,同时完善的测试对于项目重构也是非常有好处的,能够很大程度上检测是否有发生一些破坏性的变更。

以上就是C# 单元测试全解析的详细内容,更多关于C# 单元测试的资料请关注我们其它相关文章!

(0)

相关推荐

  • 详解C# WebApi 接口测试工具:WebApiTestClient

    前言:这两天在整WebApi的服务,由于调用方是Android客户端,Android开发人员也不懂C#语法,API里面的接口也不能直接给他们看,没办法,只有整个详细一点的文档呗.由于接口个数有点多,每个接口都要详细说明接口作用.参数类型.返回值类型等等,写着写着把博主惹毛了,难道这种文档非要自己写不成?难道网上没有这种文档的展示工具吗?带着这两个问题,在网络世界里寻找,网络世界很奇妙,只要你用心,总能找到或多或少的帮助!这不就被博主找到了这个好用的组件:WebApiTestClient.它对于接

  • 关于Unity C# Mathf.Abs()取绝对值性能测试详解

    前言 之前有人提到过取绝对值时 直接写三目运算符比用Mathf.Abs()效率高 没觉得能高太多 今天测了一下 真是不测不知道 一测吓一跳 直接写三目运算符比Mathf.Abs()效率高2-3倍 这性能差距有点不太合理啊! 看下源码发现 很多Mathf的方法就是多封装了一层Math里的方法 把double型转成float型了 即便很简单得方法也没有重新实现 官方有点偷懒了 所以性能差距才会这么大 以后要求性能高的地方要注意 老老实实写一遍 能提升不少性能 测试代码: using UnityEng

  • 京东联盟C#接口测试示例分享

    京东联盟C#接口的下载地址为: http://jos.jd.com/doc/channel.htm?id=285 下载后,默认是一个控制台程序,核心库和demo程序在一个项目中.这里我把核心库独立成了Dll项目. 接口使用流程是,初始化DefaultJdClient类,然后调用需要的接口类,传入参数,执行获取返回结果. 注意,使用前请先修改bin目录下的config.json文件,配置appkey等信息,格式如下: { "appkey":"11111", "

  • C#/.Net 中快速批量给SQLite数据库插入测试数据

    使用transaction: var stopwatch = new Stopwatch(); using (var cmd = new SQLiteCommand(db_con)) using (var transaction = db_con.BeginTransaction()) { stopwatch.Reset(); stopwatch.Start(); foreach (var item in sorted) { sql = string.Format("insert into db

  • C#使用String和StringBuilder运行速度测试及各自常用方法简介

    对Sting和StirngBuilder进行速度测试 使用Stopwatch 秒表计时器类(注意引用命名空间System.Diagnostics;)中的方法,Start()开始计时,Stop()停止计时,属性Elapsed:返回开始到结束的时间间隔 然后对Sting类型的变量和Stringbuilder的对象进行相同的操作,我这里是让他们添加50000个字符 代码和运行结果如下: String用时:约1.6s StringBuilder用时:约0.007s using System; using

  • c#测试本机sql运算速度的代码示例分享

    复制代码 代码如下: using System;using System.Collections.Generic;using System.Text;using System.Data.SqlClient; namespace ConsoleApplication2{    class Program    {        static void Main(string[] args)        {            SqlConnection conn = new SqlConnec

  • c#测试反射性能示例

    Activator.CreateInstance和AssemblyCreateInstance性能测试 复制代码 代码如下: using System;using System.Collections.Generic;using System.Diagnostics;using System.Linq;using System.Security.Cryptography;using System.Text;using HelloWorld.ServiceReference1;using Syst

  • C#控制台下测试多线程的方法

    本文实例讲述了C#控制台下多线程实现方法.分享给大家供大家参考.具体如下: class Program { static void Main(string[] args) { ThreadStart num = new ThreadStart(PrintNum); Thread ConstrolNum = new Thread(num); ThreadStart str = new ThreadStart(PrintStr); Thread ConstrolStr = new Thread(st

  • C#建立测试用例系统的示例代码

    引言 很多时候,需要对类中的方法进行一些测试,来判断是否能按要求输出预期的结果. C#提供了快速创建单元测试的方法,但单元测试不仅速度慢不方便,大量的单元测试还会拖慢项目的启动速度. 所以决定自己搞个方便的测试用例. 控制台调用 只需要简简单单的一句话 测试用例.注册并Print(EnumEx.Name); 结果画面 测试用例的实现 /// <summary> /// 提供测试用例的注册和运行功能,用来比对结果和预期值是否相同,向控制台输出结果. /// </summary> pu

  • C#使用base64对字符串进行编码和解码的测试

    需要引入命名空间: using System; using System.Text; 解码: public static string UnBase64String(string value) { if (value == null || value == "") { return ""; } byte[] bytes = Convert.FromBase64String(value); return Encoding.UTF8.GetString(bytes);

  • C#代码性能测试类(简单实用)

    介绍: 可以很方便的在代码里循环执行 需要测试的函数  自动统计出执行时间,支持多线程. 使用方法: PerformanceTest p = new PerformanceTest(); p.SetCount(10);//循环次数(默认:1) p.SetIsMultithread(true);//是否启动多线程测试 (默认:false) p.Execute( i => { //需要测试的代码 Response.Write(i+"<br>"); System.Threa

  • 使用 BenchmarkDotNet 对 C# 代码进行基准测试

    BenchmarkDotNet 是一个轻量级,开源的,强大的 .NET 工具包,它可以将你的方法转化为基准并跟踪这些方法,最后对这些方法的性能提供一些测试报告,使用 BenchmarkDotNet 玩 基准测试 是非常容易的. 你可以利用 BenchmarkDotNet 在 .NET Framework 和 .NET Core 应用程序上实现基准测试,在这篇文章中,我们将会讨论如何在 .NET Core 中实现基准测试. 安装 BenchmarkDotNet 要想使用 BenchmarkDotN

  • c# 插入数据效率测试(mongodb)

    mongodb的数据插入速度是其一个亮点,同样的10000条数据,插入的速度要比Mysql和sqlserver都要快,当然这也是要看使用者怎么个使用法,你代码如果10000次写入使用10000次连接,那也是比不过其他数据库使用事务一次性提交的速度的. 同样,mongo也提供的一次性插入巨量数据的方法,因为mongodb没有事务这回事,所以在在C#驱动里,具体方法是InsertManyAsync()一次性插入多个文档.与之对应的是InsertOneAsync,这个是一次插入一个文档: Insert

随机推荐