这次来联系怎么用VS2015来进行C#代码的单元测试管理,首先,正好上次写了一个C#的WordCount程序,就用它来进行单元测试联系吧。

首先,根据VS2015的提示,仅支持在共有类或共有方法中支持创建单元测试。所以,如果我们要测试私有或是保护的类和方法,是要先将他们暂时设定成公有类型。

在VS2015中创建单元测试非常简单,只要在我们想测试的地方点击右键,就会出现 “创建单元测试” 选项。

如果发现菜单没有显示,可以参照这篇博客进行设置。http://www.bubuko.com/infodetail-1370830.html

单击 “创建单元测试” 后,会出项如下对话框。不用修改,保持默认选项就可以。

点击“确定”,耐心等待一会。

创建完成后,会出项一个名为 “WCTests” 的文件,文件初始代码为

 using Microsoft.VisualStudio.TestTools.UnitTesting;
using wc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace wc.Tests
{
[TestClass()]
public class WCTests
{
[TestMethod()]
public void WCTest()
{
Assert.Fail();
} [TestMethod()]
public void OperatorTest()
{
Assert.Fail();
}
}
}

在进行单元测试时,主要使用的是 Assert 类,他的用发有很多,详细用法可以参照 https://msdn.microsoft.com/zh-cn/library/microsoft.visualstudio.testtools.unittesting.assert.aspx

下面给出我们要进行测试的代码,为了方便测试,我们对其中代码输出的部分进行了修改,将原先控制台输出的部分改成了函数返回。

 public class WC
{
private string sFilename; // 文件名
private string[] sParameter; // 参数数组
private int iCharcount; // 字符数
private int iWordcount; // 单词数
private int iLinecount; // 行 数
private int iNullLinecount; // 空行数
private int iCodeLinecount; // 代码行数
private int iNoteLinecount; // 注释行数 // 初始化
public WC()
{
this.iCharcount = ;
this.iWordcount = ;
this.iLinecount = ;
this.iNullLinecount = ;
this.iCodeLinecount = ;
this.iNoteLinecount = ;
}
// 控制信息
public string Operator(string[] sParameter, string sFilename)
{
this.sParameter = sParameter;
this.sFilename = sFilename; string retrun_str = ""; foreach (string s in sParameter)
{
if(s == "-x")
{
string resultFile = "";
OpenFileDialog fd = new OpenFileDialog();
fd.InitialDirectory = "D:\\Patch";
fd.Filter = "All files (*.*)|*.*|txt files (*.txt)|*.txt";
fd.FilterIndex = ;
fd.RestoreDirectory = true;
if (fd.ShowDialog() == DialogResult.OK)
{
resultFile = fd.FileName;
//Console.WriteLine("文件名:{0}", resultFile);
SuperCount(resultFile);
BaseCount(resultFile);
retrun_str = DisplayAll();
}
break;
}
// 遍历文件
else if (s == "-s")
{
try
{
string[] arrPaths = sFilename.Split('\\');
int pathsLength = arrPaths.Length;
string path = ""; // 获取输入路径
for (int i = ; i < pathsLength - ; i++)
{
arrPaths[i] = arrPaths[i] + '\\'; path += arrPaths[i];
} // 获取通配符
string filename = arrPaths[pathsLength - ]; // 获取符合条件的文件名
string[] files = Directory.GetFiles(path, filename); foreach (string file in files)
{
//Console.WriteLine("文件名:{0}", file);
SuperCount(file);
BaseCount(file);
retrun_str = Display();
}
break;
}
catch (IOException ex)
{
//Console.WriteLine(ex.Message);
return "";
}
}
// 高级选项
else if (s == "-a")
{
//Console.WriteLine("文件名:{0}", sFilename);
SuperCount(sFilename);
BaseCount(sFilename);
retrun_str = Display();
break;
}
// 基本功能
else if (s == "-c" || s == "-w" || s == "-l")
{
//Console.WriteLine("文件名:{0}", sFilename);
BaseCount(sFilename);
retrun_str = Display();
break;
}
else
{
//Console.WriteLine("参数 {0} 不存在", s);
break;
}
}
Console.WriteLine("{0}", retrun_str);
return retrun_str;
} // 统计基本信息:字符数 单词数 行数
private void BaseCount(string filename)
{
try
{
// 打开文件
FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
StreamReader sr = new StreamReader(file);
int nChar;
int charcount = ;
int wordcount = ;
int linecount = ;
//定义一个字符数组
char[] symbol = { ' ', ',', '.', '?', '!', ':', ';', '\'', '\"', '\t', '{', '}', '(', ')', '+' ,'-',
'*', '='};
while ((nChar = sr.Read()) != -)
{
charcount++; // 统计字符数 foreach (char c in symbol)
{
if(nChar == (int)c)
{
wordcount++; // 统计单词数
}
}
if (nChar == '\n')
{
linecount++; // 统计行数
}
}
iCharcount = charcount;
iWordcount = wordcount + ;
iLinecount = linecount + ;
sr.Close();
}
catch (IOException ex)
{
Console.WriteLine(ex.Message);
return;
}
} // 统计高级信息:空行数 代码行数 注释行数
private void SuperCount(string filename)
{
try
{
// 打开文件
FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
StreamReader sr = new StreamReader(file);
String line;
int nulllinecount = ;
int codelinecount = ;
int notelinecount = ;
while ((line = sr.ReadLine()) != null)
{
line = line.Trim(' ');
line = line.Trim('\t');
// 空行
if (line == "" || line.Length <= )
{
nulllinecount++;
}
// 注释行
else if(line.Substring(, ) == "//" || line.Substring(, ) == "//")
{
notelinecount++;
}
// 代码行
else
{
codelinecount++;
}
}
iNullLinecount = nulllinecount;
iCodeLinecount = codelinecount;
iNoteLinecount = notelinecount;
sr.Close();
}
catch (IOException ex)
{
Console.WriteLine(ex.Message);
return;
}
}
// 打印信息
private string Display()
{
string return_str = ""; foreach (string s in sParameter)
{
if (s == "-c")
{
//Console.WriteLine("字 符 数:{0}", iCharcount);
return_str += "字符数:"+iCharcount.ToString();
}
else if (s == "-w")
{
//Console.WriteLine("单 词 数:{0}", iWordcount);
return_str += "单词数:" + iWordcount.ToString();
}
else if (s == "-l")
{
//Console.WriteLine("总 行 数:{0}", iLinecount);
return_str += "总行数:" + iLinecount.ToString();
}
else if(s == "-a")
{
//Console.WriteLine("空 行 数:{0}", iNullLinecount);
//Console.WriteLine("代码行数:{0}", iCodeLinecount);
//Console.WriteLine("注释行数:{0}", iNoteLinecount);
return_str += "空行数:" + iNullLinecount.ToString();
return_str += "代码行数:" + iCodeLinecount.ToString();
return_str += "注释行数:" + iNoteLinecount.ToString();
}
}
//Console.WriteLine();
return return_str;
}
private string DisplayAll()
{
string return_str = "";
foreach (string s in sParameter)
{
//Console.WriteLine("字 符 数:{0}", iCharcount);
//Console.WriteLine("单 词 数:{0}", iWordcount);
//Console.WriteLine("总 行 数:{0}", iLinecount);
//Console.WriteLine("空 行 数:{0}", iNullLinecount);
//Console.WriteLine("代码行数:{0}", iCodeLinecount);
//Console.WriteLine("注释行数:{0}", iNoteLinecount);
return_str += "字符数:" + iCharcount.ToString();
return_str += "单词数:" + iWordcount.ToString();
return_str += "总行数:" + iLinecount.ToString();
return_str += "空行数:" + iNullLinecount.ToString();
return_str += "代码行数:" + iCodeLinecount.ToString();
return_str += "注释行数:" + iNoteLinecount.ToString();
}
//Console.WriteLine();
return return_str;
}
}

接下来,我们对测试代码进行修改,在我们进行单元测试时,某种程度上就是将我们人工给出的程序运行结果与程序实际输出结果进行比较,所以单元测试的过程一般分为 3 步:

  • 给出我们期望的结果 expected
  • 执行需测试代码,返回结果 actual
  • 比较 actual 和 expected

下面以 WC 程序执行 -c 参数对 123.txt 文件进行统计的功能为例进行测试,我们将测试代码修改如下,其中 AreEqual 方法用于对期望值与实际值进行比较。

 using Microsoft.VisualStudio.TestTools.UnitTesting;
using wc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace wc.Tests
{
[TestClass()]
public class WCTests
{
[TestMethod()]
public void WCTest()
{
// arrange
string expected = "字符数:138";
WC testwc = new WC(); // act
string[] opar = new string[];
opar[] = "-c"; string actual = testwc.Operator(opar, @"D:\学习\我的工程\软件工程\wc\wc\wc\123.txt"); // assert
Assert.AreEqual(expected, actual);
}
}
}

"123.txt" 文件为

我们预期的测试结果是此文件有138个字符,所以会输出 “字符数:138” ;我们来看看测试的结果,点击右键,选择 “运行测试” ,选项测试通过了。

我们现在给出一个错误的预期来看看结果会如何,我们现在认为 "123.txt" 文件有50个字符。

系统会提示出错,并且给出实际值与期望值分别是多少。至此,我们已经完成了简单的C#单元测试。接下来,只需要对测试代码进行修改,测试跟多的样例,来对代码进行测试。

基于C#的单元测试(VS2015)的更多相关文章

  1. 编写基于Property-based的单元测试

    编写基于Property-based的单元测试 作为一个开发者,你可能认为你的职责就是编写代码从而完成需求.我不敢苟同,开发者的工作是通过软件来解决现实需求,编写代码只是软件开发的其中一个方面,编写可 ...

  2. SpringBoot框架下基于Junit的单元测试

    前言 Junit是一个Java语言的单元测试框架,被开发者用于实施对应用程序的单元测试,加快程序编制速度,同时提高编码的质量.是一个在发展,现在已经到junit5,在javaEE开发中与很多框架相集成 ...

  3. 基于spring 的单元测试

    需要引用的依赖: import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguratio ...

  4. Java编程思想-基于注解的单元测试

    Junit的测试方法命名不一定以test开头 上面介绍的atunit已经很老了,现在junit测试框架已经基本注解了

  5. 基于junit的单元测试类编写

    首先定义抽象类BaseTest package com.geostar.gfstack.operationcenter.common.util; import com.google.gson.Gson ...

  6. 如何写好、管好单元测试?基于Roslyn+CI分析单元测试,严控产品提测质量

    上一篇文章中,我们谈到了通过Roslyn进行代码分析,通过自定义代码扫描规则,将有问题的代码.不符合编码规则的代码扫描出来,禁止签入,提升团队的代码质量. .NET Core技术研究-通过Roslyn ...

  7. WeText项目:一个基于.NET实现的DDD、CQRS与微服务架构的演示案例

    最近出于工作需要,了解了一下微服务架构(Microservice Architecture,MSA).我经过两周业余时间的努力,凭着自己对微服务架构的理解,从无到有,基于.NET打造了一个演示微服务架 ...

  8. Javascript单元测试Unit Testing之QUnit

    body{ font: 16px/1.5em 微软雅黑,arial,verdana,helvetica,sans-serif; }           QUnit是一个基于JQuery的单元测试Uni ...

  9. Java单元测试技术1

    另外两篇关于介绍easemock的文章:EasyMock 使用方法与原理剖析,使用 EasyMock 更轻松地进行测试 摘要:本文针对当前业软开发现状,先分析了WEB开发的技术特点和单元测试要解决的问 ...

随机推荐

  1. SSE图像算法优化系列五:超高速指数模糊算法的实现和优化(10000*10000在100ms左右实现)。

    今天我们来花点时间再次谈谈一个模糊算法,一个超级简单但是又超级牛逼的算法,无论在效果上还是速度上都可以和Boxblur, stackblur或者是Gaussblur想媲美,效果上,比Boxblur来的 ...

  2. 【翻译】停止学习框架(Stop Learning Frameworks)

    原文地址:https://sizovs.net/2018/12/17/stop-learning-frameworks/.翻译的比较生硬,大家凑合看吧. 我们作为程序员,对技术要时刻保持着激情,每天都 ...

  3. mysql真的不能做搜索引擎吗?

    大家都对电商的商品查询并不陌生,比如我们想根据商品名称查询所有商品信息. 有些技术的童鞋第一念头是搜索引擎:有些技术的童鞋第一念头是模糊查询,如like?(如果商品信息存放到mysql里,我们一般使用 ...

  4. rem布局原理深度理解(以及em/vw/vh)

    一.前言 我们h5项目终端适配采用的是淘宝那套<Flexible实现手淘H5页面的终端适配>方案.主要原理是rem布局.最近和别人谈弹性布局原理,发现虽然已经使用了那套方案很久,但是自己对 ...

  5. fiddler对Iphone6s进行抓包教程

    1.下载fiddler_4.6,点击下一步直接安装. 2.打开fiddler,选择tools-options,在https中勾选decrypt https traffic和ignore server ...

  6. 一张图读懂PBN飞越转弯衔接TF/CF航段计算

    在PBN旁切转弯的基础上,再来看飞越转弯接TF(或CF)航段,保护区结构上有些相似,只是转弯拐角处的保护区边界有“简化”,其余部分是相近的. FlyOver接TF段的标称航迹有一个飞越之后转弯切入航迹 ...

  7. KM算法及其应用

    在二分图匹配中有最大匹配问题,使用匈牙利算法或者网络流相关算法解决,如果给每条边增加一个权值,求权值和最大的匹配方案就叫做最大权匹配问题.其实之前所说的最大匹配就是权值为1的最大权匹配. 求最大权完备 ...

  8. Java基础——Oracle(五)

    一.Oracle  中的分页 1) select * from emp; 2)select * ,rownum from emp; //这样写不行 3)select ename,job,sal,row ...

  9. 接触Java的15天,初步了解面向对象

    面向对象的三打特征:封装 ,继承 ,多态 . 图老师给的,叫我们好好看一看 对象(object):一个杯子,一台电脑,一个人,一件衣服  等,都可以称为对象. 类:类是对象的抽象的分类:比如,人类进行 ...

  10. ubuntu安装docker以及基本用法

    ubuntu安装docker以及基本用法 一.安装 安装前先更新apt-get源到最新版本 apt-get update 使用ubuntu自带的docker安装包安装docker apt-get in ...