这次来联系怎么用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. 自己动手实现java数据结构(四)双端队列

    1.双端队列介绍 在介绍双端队列之前,我们需要先介绍队列的概念.和栈相对应,在许多算法设计中,需要一种"先进先出(First Input First Output)"的数据结构,因 ...

  2. elasticsearch数据过期删除处理

    一.概述 使用elasticsearch收集日志进行处理,时间久了,很老的数据就没用了或者用途不是很大,这个时候就要对过期数据进行清理.这里介绍两种方式清理这种过期的数据. 1.curator 关于版 ...

  3. linux nohup

    nohup RAILS_ENV=production bundle exec XXXX & nohup RAILS_ENV=production bundle exec XXXX >/d ...

  4. 发布webservice之后调用不通

    在websrvice发布文件的webconfig中加入 <httpRuntime maxRequestLength="102400" />  <webServic ...

  5. 深入理解Java 8 Lambda(类库篇)

    背景(Background) 自从lambda表达式成为Java语言的一部分之后,Java集合(Collections)API就面临着大幅变化.而 JSR 355(规定了 Java lambda 表达 ...

  6. Python 简单的远程执行命令

    client端执行命令,server端返回命令结果 # server 端 import socket, subprocess sk = socket.socket() address=('127.0. ...

  7. 【读书笔记】iOS-解析JSON

    JSON相比XML最显著的优点是不需要使用重量级的解析库,因为其本身就是面向数据的,而且非常容易转换成哈希字典.除此之外,JSON文档相比同样的XML文档更小.在网络宽带有限的情况下,你很容易在Iph ...

  8. 【读书笔记】iOS-Interface Builder

    IBOutlet或IBAction符号对编译不产生任何影响,它们只是标记,用于告诉Xcode这些对象可以和UI控件进行关联,以便于在编辑Interface Builder上的UI控件的时候Xcode可 ...

  9. ionic 一些常见问题和命令

    最近项目需要用到ionic就马上去撸,但是做下来发现官方文档的native插件,按照文档来做也遇到很多坑或者暂时想不出办法实现的. ionic这种属于跨平台的开发,是适用于比较常见通用的平台,安卓机, ...

  10. 解决如下问题:You are using pip version 8.1.1, however version 18.0 is available. You should consider upgrading via the 'pip install --upgrade pip' command.

    问题描述: 今天想学习一下TUM数据集RGBD-Benchmark工具的使用,利用python进行相关操作时,缺少一个第三方模块,于是打算用pip进行安装,便出现如下图所示的问题. 解决办法: 执行如 ...