摘要:本教程不会介绍单元测试的基本理论知识,也不会和大家讨论在实际项目中是否需要写单元测试代码的问题。但是如果你此时想使用VS中的单元测试的工具来测试某个方法是否正确,可你又从来没真正实践过,那么本教程将带你一步一步使用VS2010集成的Unit Test进行断言(Assert)式验证数据的正确性,及代码覆盖率的查看。

关键词:Unit Test、单元测试、代码覆盖率、AssertTwifly

正文:

在本入门教程中我们假设来测试一个简单的加法运算方法是否正确。该方法能够接受任意个参数,参数类型可以是整型、字符型、浮点型,对于其他复杂类型我们这里暂时忽略。既然作为入门教程,那么下面我们按照详细的步骤开始。

1、    先创建一个空白解决方案(文件—>新建—>项目—>已安装的模版—>其他项目类型—>Visual Studio解决方案-->空白解决方案)命名为TestUnit。

2、    在新创建的解决方案(TestUnit)鼠标右键,选择添加—>新建项目—>控制台应用程序。

如下图所示:

3、    在控制台应用程序中,我们添加一个Operation类。添加一个简单的Add方法,该方法能对一个dynamic类型的列表的各项求和,简单地,我们这里假设传入的类型只可能是int、double、string类型,所以不对其他类型做异常捕捉。代码如下:

public class Operation

{

public static dynamic Add(List<dynamic> numbers)

{

dynamic sum = 0;

foreach (var n in numbers)

{

var s = n;

if (s is string)

{

s = -Convert.ToDouble(n);    //我们这里故意在转换前加了一个取反运算

}

sum += s;

}

return sum;

}

}

4、    现在我们来对Add方法做下单元测试。将光标放在Add方法名上,然后右键选择“创建单元测试(C)…”,如下图所示:

5、这时会弹出“创建单元测试”窗口,如下图所示,一般情况下直接点击确定即可。

 
 

6、如果直接点击确定按钮,系统将按照默认的命名规则(直接加Test后缀)生成测试文件。当然你也可以点击上图中的“设置…”按钮,在弹出的“测试生成设置”中进行规则修改。如下图所示:

7、因为这是我们第一次创建单元测试项目,所以在输出选项中,我们选择默认的“创建新的Visual C# 测试项目”。在单击“确定”按钮后,要求我们填写测试项目的名称,名称自己随便,这里我们就用默认的TestProject1。点击“创建”即可。如果我们以后还对另一个方法进行单元测试,我们就可以在输出项目中直接选择“TestProject1”了,而不比再创建新的测试项目。如下图所示:

8、    这时,在解决方案下面,系统自动为我们创建了TestProject1测试项目和Solution Items(解决方案项)文件夹。

 

9、双击TestProject1测试项目下的OperationTest.cs文件,我们看一下系统为我们自动生成的测试代码。会发现主要有一下几点:

?  在代码文件顶部增加了一个:using Microsoft.VisualStudio.TestTools.UnitTesting;

?  在生成的OperationTest类上标记了[TestClass()],即使用了TestClassAttribute

?  对测试类的方法AddTest标记了[TestMethod()]

?  在测试类OperationTest中,定义了一个类型为TestContext的变量testContextInstance

?  附加测试特性

10、我们现在要做的就是要对AddTest方法编写测试代码,一般情况下只需要简单地将TODO部分填写完整,将默认的代码:

改成如下测试代码进行第一组测试:

/// <summary>

///Add 的测试

///</summary>

[TestMethod()]

public void AddTest()

{

List<dynamic> numbers = new List<dynamic>() { 1, 2, 3, 4, 5 };

dynamic expected = 15;

dynamic actual;

actual = Operation.Add(numbers);

Assert.AreEqual(expected, actual);

}

这个方法就是对整型1、2、3、4、5累加进行测试,我们期望的结果是15。Assert类的AreEqual方法用于验证实际结果和期望值是否相等。Assert断言类包含很多方法用于比较,在测试方法中,可以调用任意数量的 Assert 类方法,如 Assert.AreEqual()。Assert 类有很多方法可供选择,其中许多方法具有若干重载。详情可以参考MSDN的Assert类。

默认生成的代码中Assert.Inconclusive 语句用于指示该测试尚未准备好,不能运行(不能确定结果是否正确),所以当我们写好测试代码后,Assert.Inconclusive语句就可以删除了。

11、运行单元测试。打开测试视图(测试-->窗口-->测试视图),测试视图中会以列表的方式显示测试方法。右键菜单选择“运行选定内容”即可执行对该方法的测试,如下图所示:

 
 

VS2010接到测试的指令后,在测试完成后会自动弹出“测试结果”窗口,结果显示通过,表示测试结果值和预期结果相同。

12、上面一组单元测试(整型)结果是通过,但是我们知道对字符串操作是故意留有错误,但是实际过程中,那段代码并没有执行。所以我们还要对字符格式的数字进行测试,当然还有浮点型、负数等等,这些可以都单独测试,也可以一起测试。把测试代码改成:

/// <summary>

///Add 的测试

///</summary>

[TestMethod()]

public void AddTest()

{

List<dynamic> numbers = new List<dynamic>() { 1, 2, 3, 4, 5 };

dynamic expected = 15;

dynamic actual;

actual = Operation.Add(numbers);

Assert.AreEqual(expected, actual);

List<dynamic> numbers2 = new List<dynamic>() { "1", "2", "3", "4" };

dynamic expected2 = 10;

dynamic actual2;

actual2 = Operation.Add(numbers2);

Assert.AreEqual(expected2, actual2);

List<dynamic> numbers3 = new List<dynamic>() { "1", 2.5, 3, "4.5", 5, 6 };

dynamic expected3 = 22;

dynamic actual3;

actual3 = Operation.Add(numbers3);

Assert.AreEqual(expected3, actual3);

}

我们再进行一次测试(第二组测试)。每次测试代码修改后,会提示我们刷新更新,直接点击刷新按钮即可。

 

看看测试结果如何:

 

这个时候我们发现测试显示未通过,右键菜单单击“查看测试结果详细信息”,如下图所示:

13、错误消息提示期望指为10,但实际结果为-10,我们很容易知道是下面组数据出了问题:

List<dynamic> numbers2 = new List<dynamic>() { "1", "2", "3", "4" };

找到代码:s = -Convert.ToDouble(n);    //我们这里故意在转换前加了一个取反运算,把前面的取反运算符去掉,改成:s = Convert.ToDouble(n);    再进行一次测试,测试结果会按预期的方式显示为通过。

14、调试单元测试。上面能一下子就把错误修改,是因为错误是我们故意设置的。在实际开发中,找错误也许并不明显,通常是需要调试后才容易找到。调试单元测试和平时断点测试是一样的,在需要的地方设置断点后,在测试视图中右键选择“调试选定内容”,接下来就是大家所熟悉的断点调试步骤了。如下图所示:

15、查看代码覆盖率。单元测试的编写,涉及到很多要求,但是最基本的就是需要编写多组数据对各个分支代码都至少需要执行一遍。如我们前面第一组直接测试整型相加(1、2、3、4、5)测试结果15为通过,没找到潜在的错误,是因为有些代码没被执行。查看代码覆盖率就能帮助你检测测试数据是否会覆盖所有分支代码。

如下图所示,右键选择“覆盖率结果”,可以查看代码覆盖率。

第一组数据测试代码覆盖率:

第二组数据测试代码覆盖率:

16、代码覆盖率默认演示显示说明:

颜色代码

说明

浅蓝色

指示在测试运行过程中执行了整个代码行。

浅褐色

指示在测试运行过程中仅执行了代码行的部分代码块。

红棕色

指示在测试运行过程中未执行此行。

当然这些默认颜色可以在工具菜单下的选项中进行设置,如下图所示:

17、如果在查看代码覆盖率中出现如下提示,则我们需要简单配置一下

在“测试视图”中,找到Solution Items(解决方案项)文件夹下的Local.testsettings,双击打开“测试设置”窗口,选择“数据和诊断”,将代码覆盖率设置为启用,然后点击“配置”对代码覆盖率进行配置,如下图所示:

在我们的控制台应用程序前打勾,然后点击确定按钮

最后对“测试设置”点击“应用”按钮完成代码覆盖率的配置。重新运行测试,就可以查看代码覆盖率了。

到这里已经完成了如何简单使用VS2010自带的单元测试工具进行断言式Assert条件测试,当然以后我们还可能接触到CollectionAssert类来比较集合对象、StringAssert 类来对字符串进行比较等等,在后面的教程中我们将接触到。

VS单元测试入门实践教程的更多相关文章

  1. VS2010单元测试入门实践教程

    单元测试的重要性这里我就不多说了,以前大家一直使用NUnit来进行单元测试,其实早在Visual Studio 2005里面,微软就已经集成了一个叫Test的专门测试插件,经过几年的发展,这个工具现在 ...

  2. 最火的分布式 HTAP 数据库 TiDB - 入门实践教程

    偶然在某篇博客看到了 TiDB,一个融合 OLTP 和 OLAP 的分布式开源数据库, GitHub 上 Star 很多,然后 watch 了,发现 commit 和 pull request 一直都 ...

  3. Redis(9)——史上最强【集群】入门实践教程

    一.Redis 集群概述 Redis 主从复制 到 目前 为止,我们所学习的 Redis 都是 单机版 的,这也就意味着一旦我们所依赖的 Redis 服务宕机了,我们的主流程也会受到一定的影响,这当然 ...

  4. 百亿数据百亿花, 库若恒河沙复沙,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang数据库操作实践EP12

    Golang可以通过Gorm包来操作数据库,所谓ORM,即Object Relational Mapping(数据关系映射),说白了就是通过模式化的语法来操作数据库的行对象或者表对象,对比相对灵活繁复 ...

  5. MyBatis入门学习教程-使用MyBatis对表执行CRUD操作

    上一篇MyBatis学习总结(一)--MyBatis快速入门中我们讲了如何使用Mybatis查询users表中的数据,算是对MyBatis有一个初步的入门了,今天讲解一下如何使用MyBatis对use ...

  6. 做中学之Vim实践教程

    做中学之Vim实践教程 Vim VIM是一个非常好的文本编辑器,很多专业程序员使用VIM编辑代码,即使以后你不编写程序,只要跟文本打交道,都应该学学VIM,可以浏览参考一下普通人的编辑利器--Vim这 ...

  7. MVC5+EF6 入门完整教程11--细说MVC中仓储模式的应用

    摘要: 第一阶段1~10篇已经覆盖了MVC开发必要的基本知识. 第二阶段11-20篇将会侧重于专题的讲解,一篇文章解决一个实际问题. 根据园友的反馈, 本篇文章将会先对呼声最高的仓储模式进行讲解. 文 ...

  8. MVC5+EF6 入门完整教程12--灵活控制Action权限

    大家久等了. 本篇专题主要讲述MVC中的权限方案. 权限控制是每个系统都必须解决的问题,也是园子里讨论最多的专题之一. 前面的系列文章中我们用到了 SysUser, SysRole, SysUserR ...

  9. 全文搜索引擎Elasticsearch入门实践

    全文搜索引擎Elasticsearch入门实践 感谢阮一峰的网络日志全文搜索引擎 Elasticsearch 入门教程 安装 首先需要依赖Java环境.Elasticsearch官网https://w ...

随机推荐

  1. ionic安装

    npm set registry http://registry.cnpmjs.org/ 设置淘宝镜像

  2. a:hover span 隐藏/显示 问题

    :hover是我们在CSS设计中最常运用的伪类之一,许多绚丽效果的实现离不开伪类:hover,比如我们常见的纯CSS菜单.相册效果等等. 或许用了这么久的伪类:hover,还有部分朋友还不完全了解ho ...

  3. java 时间格式化(2016.04.12 12:32:55)

    输入的时间格式如:2016.04.12 12:32:55所示: 想要获取一定格式的日期,时间的方法 String startString = "2016.04.25 12:25:44&quo ...

  4. sql server数据库主键自增一插入特定值

    ID identity(1,1) SET IDENTITY_INSERT TableName ON INSERT TableName(ID) VALUES(110) SET IDENTITY_INSE ...

  5. [jquery] 图片热区随图片大小自由缩放

    在图片上直接画出带超级链接热区元素map和area相信大家并不陌生,Dreamweaver等网页制作软件都有直接在图片上绘制带超级链接的热区工具,但是直接绘制的热区是不能随着图片自适应放大和缩小的,现 ...

  6. queue 之团队队列(摘)

    有t个团队的人正在排一个长队.每次新来一个人时,如果他有队友在排队,那么这个新人会插队到最后一个队友的身后.如果没有任何一个队友排队,则他会排到长队的队尾. 输入每个团队中所有队员的编号,要求支持如下 ...

  7. (转载) socket:10038错误{winSock的一个bug:当closesocket多次错误使用时会导致问题}

    这几天想在一个开源的代码上进行修改,以期研发出一个产品出来.       程序原来是单线程网络程序,需要修改为多线程,修改之后,总是出问题,辅助线程中的recv函数总是运行一阵子之后收到长度为-1的数 ...

  8. android studio error configuration with name default not found

    Android Studio报错: android studio error configuration with name default not found 在进行sync的时候,提示Error: ...

  9. Java 中级IO流基础及主要API编程

    1. IO流基础知识,流 是字节从源到目的地的运行的轨迹,次序是有意义的, 字节会按照次序进行传递, 比如Hello World 在下图中的传递的轨迹.该图形象的解释了IO中流的概念.流中全是字节.2 ...

  10. 简单C# 验证类

    using System; using System.Text.RegularExpressions; namespace bobomousecom.crm { /// <summary> ...