使用MSTest进行单元测试
我之前写过一篇XUNit的简介:使用Xunit来进行单元测试。Xunit在当时确实是一个最简单易用的测试框架,然而,随着发展,Xunit也变得复杂了不少,光写一个最简单的测试就要导入8个包。

如果在大一点的项目中使用到还罢了,但如果只是随手想写一点单元测试引入这一堆包确实看着不大舒服。于是我又看了下MS自家的MS TEST。发现随着发展,MS自家的MS TEST也改变了不少,虽然以前用过老版MS TEST的朋友基本上能拿着就用,但本文这里仍然简单的介绍一下,方便新手上路。
目前MS发布了两个版本的MS TEST:
- MS TEST V1: V1在.net framework中自带,引用Microsoft.VisualStudio.QualityTools.UnitTestFramework即可
- MS TEST V2: V2的版本依赖于两个包: MSTest.TestFramework和MSTest.TestAdapter
这两个版本使用起来还是大同小异的,MS TEST V2主要是为了.net core准备的,当然也可以在.net framework上运行,并且新加入了一些扩展。本文这里是针对MS TEST V2进行的介绍。
首先来写一个简单的用例:
[TestClass]
public class TestClass
{
[TestMethod]
public void TestPass()
{
Assert.IsTrue(true);
} [TestMethod]
public void TestFail()
{
Assert.IsTrue(false);
}
}
写完后编译即可在测试管理器上看到用例,运行它就可以看到结果了:

测试用例声明:
- 测试用例的类必须是public的,并且用TestClassAttribute标记
- 测试用例必须是public的,并且用TestMethodAttribute标记
Xunit并不需要TestClass声明,但给测试类声明也是有好处的,可以对其下的所有测试用例分组。
断言:
可以用Assert断言类来检验测试是否成功,也可以自己写帮助类抛异常检验。
构建和析构:
和Xunit非常类似,测试框架执行每个测试用例的时候,会创建测试类对象,测试用例执行完后,如果测试类是IDisposable的,会执行Dispose函数。因此,简单的做法是:
- 在测试用例类的构造函数指向数据构建操作
- 在Dispose函数中指向数据清理操作
另外,也可以通过TestInitialize和TestCleanup两个Attribute来指定额外的构建和清理函数。通过函数指定的构建和析构函数在测试异步函数的时候还是非常有用的。这样,一个测试用例执行的顺序是
- 构造函数
- TestInitialize制定的构建函数(如果有)
- 测试用例
- TestCleanup制定的清理函数(如果有)
- IDisposable. Dispose函数(如果有)
分组:
分组可以通过TestCategory标记:
[TestClass,TestCategory("MS TEST V2")]
public class TestClass
查看方式中要选择按特征分类:

这个标记也可以放在测试类,也可以放在测试用例上,效果不一样,请自行尝试。
参数传入:
这个是老版本的MS TEST的最大不足了,现在也可以通过DataRowAttribute指定测试用例的参数:
[DataTestMethod]
[DataRow(, , )]
[DataRow(, , )]
[DataRow(, , )]
public void AddTest(int n1, int n2, int sum)
{
Assert.AreEqual(sum, n1 + n2);
}
也可以指定多组参数,测试就会执行多次用例。在MS TEST V2的版本中,还可以通过ITestDataSource接口实现自定义数据源。
异常测试:
异常下现在也和xunit一样采用断言的方式捕获了。
public void TestException()
{
Assert.ThrowsException<InvalidOperationException>(() => foo()); void foo()
{
throw new InvalidOperationException();
}
}
扩展:
在MS TEST V2中,微软提供了一定的扩展支持,如下图所示(这些扩展也大部分支持MS TEST V1)

具体包括如下几点:
- 特性扩展:
通过继承TestPropety,可以更方便的为测试用例添加描述。详情:RFC 001
- 断言扩展:
通过内置的断言扩展,可以更简洁的方式定制自己的断言API。详情:RFC 002
- 执行扩展:
MSTest V2允许我们在以下两个层级加入扩展。
- 测试方法级别:允许创建自己的TestMethod特性,定制执行逻辑
- 测试类级别:允许创建自己的TestClass特性,定制内部所有测试方法的执行逻辑
详情:RFC 003
- 数据驱动扩展:
目前的MS TEST已经支持静态数据参数DataRow的支持,它的主要特点是:
- 静态数据不能满足复杂的场景需要
- 无法为多个用例共享
如果需要更复杂的数据源,可以通过ITestDataSource接口实现。
小结:
MSTEST现在也非常简单易用了。不过感觉Xunit的功能还是要多些,例如XUNIT可以暂时跳过用例,也可以修改用例名称。我这里对MS TEST V2还处于管中窥豹的阶段,后面可能会在一些项目中尝试试用一下,可能还会写一些文章继续介绍它。
参考文章:
网上也有不少好的单元测试的文章可以参考下:
使用MSTest进行单元测试的更多相关文章
- NAnt打包使用MSTest进行单元测试的配置
NAnt比较老的持续集成工具了,对于它的文章都停留在09年左右的,只有一些github上的老项目上可以很多的看见是使用这个进行集成的,估计这个当时老外用的非常多吧. 如题,NAnt如果使用单元测试,用 ...
- MSTest/NUnit 单元测试 代码覆盖率试用 OpenCover 和ReportGenerator
VS自带是单元测试代码覆盖率(VS自带这个是最佳选择)需要企业版才有.很蛋疼...... 1.下载安装OpenCover 和ReportGenerator. 关于这2个是干啥的百度下.简单说就是可以分 ...
- .NET重构—单元测试重构
.NET重构—单元测试重构 阅读目录: 1.开篇介绍 2.单元测试.测试用例代码重复问题(大量使用重复的Mock对象及测试数据) 2.1.单元测试的继承体系(利用超类来减少Mock对象的使用) 2.1 ...
- 关于C#程序的单元测试
目录 1.单元测试概念 2.单元测试的原则 3.单元测试简单示例 4.单元测试框架特性标签 5.单元测试中的断言Assert 6.单元测试中验证预期的异常 7.单元测试中针对状态的间接测试 8.单元测 ...
- VS2012 Unit Test——Microsoft Fakes入门
如题,本文主要作为在VS2012使用Fakes的入门示例,开发工具必须是VS2012或更高版本. 关于Fakes的MSDN地址:http://msdn.microsoft.com/en-us/libr ...
- Nhibernate系列学习之(一) ORM and Nhibernate入门实例解析
最近框架项目需要,数据层想使用Nhibernate,代替传统的sql语句的写法,更加使用面向对象的思维来维护实体与数据库的这层关系映射(ORM),好在之前接触过Java时学习使用了Hibernate, ...
- 最大子段和的DP算法设计及其效率测试
表情包形象取自番剧<猫咪日常> 那我也整一个 曾几何时,笔者是个对算法这个概念漠不关心的人,由衷地感觉它就是一种和奥数一样华而不实的存在,即便不使用任何算法的思想我一样能写出能跑的程序 直 ...
- NHibernate4使用Oracle.ManagedDataAccess.dll连接oracle及配置多个数据库连接
NHibernate数据库配置参数在hibernate.cfg.xml中 <?xml version="1.0" encoding="utf-8"?> ...
- .NET Core 单元测试 MSTest
.NET Core 单元测试 MSTest ,MSTest Framework 已经支持 .NET Core RC2 / ASP.NET Core RC2. 之前都是使用 xUnit.net ,现在 ...
随机推荐
- c++刷题(43/100)矩阵旋转打印
题目1:矩阵旋转打印 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则 ...
- CF232C Doe Graphs
传送门 Solution: (不理解时对着图研究一下就清楚啦!!!) sm[i]为|D(i)| (x,y,n)为x,y在D(n)中的最短路 已知sm[i-1]+1为D(i)的割点 于是x-y的最短 ...
- C. NN and the Optical Illusion(几何)
题目链接:http://codeforces.com/contest/1100/problem/C 题目大意:给你n和r,n指的是有n个圆围在里面的圆的外面,r指的是里面的圆的半径,然后让你求外面的圆 ...
- Linux驱动技术(四) _异步通知技术【转】
转自:https://www.cnblogs.com/xiaojiang1025/p/6376561.html 异步通知的全称是"信号驱动的异步IO",通过"信号&quo ...
- springcloud Zuul中异常处理细节
Spring Cloud Zuul对异常的处理整体来说还是比较方便的,流程也比较清晰,只是由于Spring Cloud发展较快,各个版本之间有差异,导致有的小伙伴在寻找这方面的资料的时候经常云里雾里, ...
- Go语言Windows 10开发环境搭建:Eclipse+GoClipse
Intel Core i5-8250U,Windows 10家庭中文版,go version go1.11 windows/amd64, Eclipse IDE for C/C++ Developer ...
- Coursera台大机器学习技法课程笔记09-Decision Tree
这是我们已经学到的(除Decision Tree外) 下面是一个典型的decision tree算法,有四个地方需要我们选择: 接着介绍了一个CART算法:通过decision stump分成两类,衡 ...
- wpf 用户自定义事件传参
//自定义传参 ,对外联系的参数 public class ImageZoomChangedEventArgs : RoutedEventArgs { /// <summary> /// ...
- linux文本编码格式转化 字幕处理
在处理字幕的时候,linux的编码格式转换很烦. 步骤: 用python先判断 其编码,再用iconv 转编码,再用awk处理格式. file不能判断吗?file有时不准. 1.python判断编码 ...
- Codeforces 772C 构造 数学 + dp + exgcd
首先我们能注意到两个数x, y (0 < x , y < m) 乘以倍数互相可达当且仅当gcd(x, m) == gcd(y, m) 然后我们可以发现我们让gcd(x, m)从1开始出发走 ...