C#中实现单元测试的示例流程_MSTest测试项目

一、单元测试简介

1.1、单元测试简介

        在《单元测试艺术》一书中对于单元测试的定义是:【一个单元测试是一段代码,这段代码调用一个工作单元(指:调用软件中的一个方法,这个方法执行过程中所发生的所有行为以及最后产生的结果的总和),并检验该工作单元的一个具体的结果。如果关于这个结果的最终假设是错误的,单元测试就失败了;一个单元测试的范围可以小到一个方法,大到多个类

1.2、单元测试的意义

        要注意:引入单元测试或有单元测试并不能证明代码质量好(应根据项目情况进行调整适配,比如优先考虑核心模块),单元测试并不是越多越好(不要忽视引入代码测试以及无效的测试所带来的维护成本【如:增加开发的时间、增加人员成本】,毕竟资源是有限的)。

        若不考虑时间成本,还是希望各位可以为代码编写高效可靠的单元测试,毕竟这对提升代码质量有帮助;而单元测试具有如下意义:

1、通过单元测试用例确保的功能,不会在后续的迭代过程中产生Bug;

2、在重构模块时,因为有单元测试覆盖,也可以大胆去做;

3、可以通过单元测试模块了解模块具体功能和预期;

4、提高代码质量,降低耦合;

二、单元测试示例流程

2.1、打开VisualStudio创建项目

1、使用VisualStudio创建一个跨平台的控制台项目(取名为:Test_UnitTest),如下图所示:

2、新建一个名为: BankAccount 的银行账户类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace test_UnitTest
{public class BankAccount{private readonly string m_customerName;private double m_balance;public BankAccount(string customerName,double balance){m_customerName = customerName;m_balance = balance;Console.WriteLine($"\n初始的余额是【{Balance}】");}public string CustomerName{get { return m_customerName; }}public double Balance{get { return m_balance; } }/// <summary>/// 借钱出去/// </summary>/// <param name="amout">金额</param>/// <exception cref="ArgumentOutOfRangeException"></exception>public void Debit(double amout){if (amout>m_balance){throw new ArgumentOutOfRangeException("amount");}if (amout<0){throw new ArgumentOutOfRangeException("amount");}m_balance += amout;Console.WriteLine($"借钱【{amout}】出去后的余额是【{Balance}】");}public const string DebitAmountExceedsBalanceMessage = "当前借出的金额超过当前的余额";public const string DebitAmountLessThanZeroMessage = "当前借出的金额小于0";/// <summary>/// 借钱出去/// </summary>/// <param name="amout">金额</param>/// <exception cref="ArgumentOutOfRangeException"></exception>public void Debit2(double amout){if (amout > m_balance){throw new ArgumentOutOfRangeException("amount",amout, DebitAmountExceedsBalanceMessage);}if (amout < 0){throw new ArgumentOutOfRangeException("amount",amout, DebitAmountLessThanZeroMessage);}m_balance += amout;Console.WriteLine($"借钱【{amout}】出去后的余额是【{Balance}】");}/// <summary>/// 贷款进来/// </summary>/// <param name="amout">金额</param>/// <exception cref="ArgumentOutOfRangeException"></exception>public void Credit(double amout){if (amout<0) {throw new ArgumentOutOfRangeException("amout");}m_balance += amout;Console.WriteLine($"贷款【{amout}】进来后的余额是【{Balance}】");}}//Class_end
}

3、运行该银行账户类

namespace test_UnitTest
{internal class Program{static void Main(string[] args){Console.WriteLine("Hello, World!");BankAccount ba = new BankAccount("张三", 11.99);ba.Credit(5.77);ba.Debit(11.22);Console.WriteLine($"当前账户的余额是 ${ba.Balance}");Console.ReadLine();}}
}

        到目前为止程序是没有报错的;但是仔细查看我们就会发现一个问题,借钱出去后,我们的银行账户应该是余额减少的;但是我们的程序却显示余额增加了,这明显是错误的;关于这样的类似错误我们可以通过单元测试来避免,修复这个Bug。

2.2、创建单元测试项目

2.2.1、新增单元测试项目,并且添加项目引用

 

2.2.2、创建单元测试类BankAccountTest.cs

将默认的UnitTest1.cs类修改名称为【BankAccountTest.cs】,默认的测试类示例如下

using Microsoft.VisualStudio.TestTools.UnitTesting;namespace BankTests
{[TestClass]public class BankAccountTests{[TestMethod]public void TestMethod1(){}}
}

其中【TestClass】标识该类是一个单元测试类;【TestMethod】标识该方法是一个单元测试方法。

2.2.3、编写一个单元测试的示例方法

单元测试方法的必备要求
序号
1必须使用 [TestMethod] 特性进行修饰
2方法必须返回 void
3单元测试方法必须不能含有参数
 Assert.AreEqual、Assert.IsTrue 等方法经常用于单元测试Assert Class (Microsoft.VisualStudio.TestTools.UnitTesting) | Microsoft Learn

①分析:编写单元测试方法以验证 BankAccount 类的 Debit 方法的行为,则至少需要检查三种行为:

  • 如果借方金额大于余额,该方法将引发 ArgumentOutOfRangeException 。

  • 如果借方金额小于零,该方法会引发 ArgumentOutOfRangeException。

  • 如果借方金额有效,该方法会从帐户余额中减去该借方金额。

②第一个单元测试方法:验证是否从帐户中提取了正确的有效金额(即小于帐户余额且大于零);将以下方法添加到该 BankAccountTests 类:

        [TestMethod]//验证借出指定的金额后是否与预期的金额相等public void Debit_WithValidAmount_UpdatesBalance(){double beginningBalance = 11.99;    //初始金额double debitAmount = 4.55;          //借出去的金额数量double expected = 7.44;             //进出金额后期望剩余的金额数量BankAccount account = new BankAccount("张三", beginningBalance);account.Debit(debitAmount);double actual = account.Balance;//判断是否相等[若不相等则抛出异常]Assert.AreEqual(expected, actual, 0.001, "该账户的金额并没有正确的借出去!!!");}

③生成并运行单元测试和解决错误

首先生成解决方案

然后选择顶部的【测试】-->【运行所有测试】结果如下: 

 最后根据单元测试的错误提示排查是由于调用账户的借出金额后的余额与期望的余额不一致导致报错,我们需要排查【account.Debit()】方法,需要将【account.Debit()】方法的 m_balance += amout;修改为 m_balance -= amout;后保存重新【运行所有测试】即可通过单元测试),如下图所示:

BankAccountTest.cs银行账户的完整单元测试类内容如下:

具体的每步细节可以查看如下的链接

C# 单元测试教程 - Visual Studio (Windows) | Microsoft Learn了解如何使用托管代码的 Microsoft 单元测试框架和 Visual Studio 测试资源管理器创建、运行和自定义单元测试系列。icon-default.png?t=N7T8https://learn.microsoft.com/zh-cn/visualstudio/test/walkthrough-creating-and-running-unit-tests-for-managed-code?view=vs-2022

using test_UnitTest;namespace UnitTest
{[TestClass]public class BankAccountTest{[TestMethod]//验证借出指定的金额后是否与预期的金额相等public void Debit_WithValidAmount_UpdatesBalance(){double beginningBalance = 11.99;    //初始金额double debitAmount = 4.55;          //借出去的金额数量double expected = 7.44;             //进出金额后期望剩余的金额数量BankAccount account = new BankAccount("张三", beginningBalance);account.Debit(debitAmount);double actual = account.Balance;//判断是否相等[若不相等则抛出异常](运行测试后发现抛出了【该账户的金额并没有正确的借出去!!!】的异常;我们此时需要排查【account.Debit()】方法,//需要将【account.Debit()】方法的 m_balance += amout;修改为 m_balance -= amout;后重新运行即可通过单元测试)Assert.AreEqual(expected, actual, 0.001, "该账户的金额并没有正确的借出去!!!");}[TestMethod]//验证借出去的金额小于零时的行为是否正确(即:应该报错)public void Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange(){double beginningBalance = 11.99;double debitAmount = -100;BankAccount bankAccount = new BankAccount("张三",beginningBalance);//使用 ThrowsException 方法断言已引发正确的异常。 除非 ArgumentOutOfRangeException 已引发,否则该方法将导致测试失败。//如果在借方金额小于零时,临时修改测试方法以引发更通用的 ApplicationException,则测试将正确运行,即测试将失败。Assert.ThrowsException<System.ArgumentOutOfRangeException>(() => bankAccount.Debit(debitAmount));}[TestMethod]//验证借出去的金额大于余额时的行为是否正确(即:应该报错)public void Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange(){double beginningBalance = 11.99;double debitAmount =20.0;BankAccount bankAccount = new BankAccount("张三", beginningBalance);//使用 ThrowsException 方法断言已引发正确的异常。 除非 ArgumentOutOfRangeException 已引发,否则该方法将导致测试失败。//如果在借方金额大于余额时,临时修改测试方法以引发更通用的 ApplicationException,则测试将正确运行,即测试将失败。Assert.ThrowsException<System.ArgumentOutOfRangeException>(() => bankAccount.Debit(debitAmount));}[TestMethod]//该测试方法解决【没有办法知道哪个条件(amount > m_balance 或 amount < 0)导致在测试期间引发异常。//我们只知道在方法中引发了一个 ArgumentOutOfRangeException。//更理想的情况是,如果我们知道是 BankAccount.Debit 中的哪个条件导致引发异常(amount > m_balance 或 amount < 0),//这样就可以确信我们的方法可以正确合理地检查其自变量。】public void Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange2(){// Arrangedouble beginningBalance = 11.99;double debitAmount = 20.0;BankAccount account = new BankAccount("张三", beginningBalance);// Acttry{account.Debit2(debitAmount);}catch (System.ArgumentOutOfRangeException e){// AssertStringAssert.Contains(e.Message, BankAccount.DebitAmountExceedsBalanceMessage);}}[TestMethod]//该测试方法解决【测试方法不会处理它原本应该处理的所有情况。//如果所测试的方法 Debit 在 debitAmount 大于余额(或小于零)时未能引发 ArgumentOutOfRangeException,则该测试方法通过。//这样并不好,因为如果未引发异常,则希望测试方法失败。这是测试方法中的一个 bug。//要解决该问题,在测试方法末尾添加 Assert.Fail 断言,处理未引发异常的情况。】public void Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange3(){// Arrangedouble beginningBalance = 11.99;double debitAmount = 20.0;BankAccount account = new BankAccount("张三", beginningBalance);// Acttry{account.Debit2(debitAmount);}catch (System.ArgumentOutOfRangeException e){// AssertStringAssert.Contains(e.Message, BankAccount.DebitAmountExceedsBalanceMessage);return;}Assert.Fail("未引发预期的异常");}}//Class_end
}

三、单元测试资料

Visual Studio 中的测试工具 - Visual Studio (Windows) | Microsoft Learn了解如何使用功能 Visual Studio 来测试代码。icon-default.png?t=N7T8https://learn.microsoft.com/zh-cn/visualstudio/test/?view=vs-2022

单元测试入门 - Visual Studio (Windows) | Microsoft Learn使用 Visual Studio 定义和运行单元测试,使代码保持正常运行并在客户之前找到错误和缺陷。icon-default.png?t=N7T8https://learn.microsoft.com/zh-cn/visualstudio/test/getting-started-with-unit-testing?view=vs-2022&tabs=dotnet%2Cmstest 单元测试基础知识 - Visual Studio (Windows) | Microsoft Learn了解 Visual Studio 测试资源管理器如何提供灵活而高效的方法来运行单元测试并查看其结果。icon-default.png?t=N7T8https://learn.microsoft.com/zh-cn/visualstudio/test/unit-test-basics?view=vs-2022#write-your-testsC# 单元测试教程 - Visual Studio (Windows) | Microsoft Learn了解如何使用托管代码的 Microsoft 单元测试框架和 Visual Studio 测试资源管理器创建、运行和自定义单元测试系列。icon-default.png?t=N7T8https://learn.microsoft.com/zh-cn/visualstudio/test/walkthrough-creating-and-running-unit-tests-for-managed-code?view=vs-2022

Assert Class (Microsoft.VisualStudio.TestTools.UnitTesting) | Microsoft LearnA collection of helper classes to test various conditions within unit tests. If the condition being tested is not met, an exception is thrown.icon-default.png?t=N7T8https://learn.microsoft.com/zh-cn/dotnet/api/microsoft.visualstudio.testtools.unittesting.assert?view=visualstudiosdk-2022

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/143823.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Inno Setup安装中文语言

以版本6.2.2为例&#xff1a; 默认安装的Inno Setup是不支持中文语言的&#xff0c;需要我们自行下载安装。 一、打开官网Inno Setup Translations (jrsoftware.org) 下载的文件如下 二、然后重命名放到Inno Setup的如下安装目录中 三、然后重启Inno Setup即可。 打包后的…

家电行业 EDI:Miele EDI 需求分析

Miele是一家创立于1899年的德国公司&#xff0c;以其卓越的工程技术和不懈的创新精神而闻名于世。作为全球领先的家电制造商&#xff0c;Miele的经营范围覆盖了厨房、洗衣和清洁领域&#xff0c;致力于提供高品质、可持续和智能化的家电产品。公司的使命是为全球消费者创造更美…

SpringMVC 学习(二)Hello SpringMVC

3. Hello SpringMVC (1) 新建 maven 模块 springmvc-02-hellomvc (2) 确认依赖的导入 (3) 配置 web.xml <!--web/WEB-INF/web.xml--> <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns"http://xmlns.jcp.org/xml/ns/javaee…

maven清理本地仓库。删除_remote.repositories文件和删除失败的jar包

1.图预览 .bat文件要和仓库在同一平级目录 REPOSITORY_PATH要改成你自己仓库的地址 2、删除.lastUpdated文件(失败的jar包) 使用.bat文件 注明&#xff1a;REPOSITORY_PATHD:\software\Java\maven\repository 改成你仓库的地址 set REPOSITORY_PATHD:\software\Java\maven\rep…

河北吉力宝以步力宝健康鞋引发的全新生活生态商

在当今瞬息万变的商业世界中&#xff0c;成功企业通常都是那些不拘泥于传统、勇于创新的先锋之选。河北吉力宝正是这样一家企业&#xff0c;通过打造一双步力宝健康鞋&#xff0c;他们以功能性智能科技穿戴品为核心&#xff0c;成功创造了一种结合智能康养与时尚潮流的独特产品…

Zotero同步论文、笔记

之前用 Mendeley[1]看论文&#xff0c;看中几个功能&#xff1a; tags&#xff0c;多标签分类&#xff0c;类似微信分组&#xff0c;用来快速筛&#xff08;已添加的&#xff09;某一类文献&#xff1b;同步&#xff0c;包括 pdf 和笔记&#xff08;高亮、便签、tags&#xff…

数链科技基于PP-ChatOCR实现合同信息抽取,准确率达98%

传统大宗商品供应链领域数字化程度低&#xff0c;存在交易环节不透明、业务流程不标准、依赖主体信用评价等问题&#xff0c;业务中存在大量营业执照、身份证、终端合同等线下单据&#xff0c;严重依赖人工线下审核&#xff0c;且数字化难度大。 不同终端、机构、仓库的单据格式…

python使用websocket实现多端数据同步,多个websocket同步消息,断开链接自动清理

我使用的是flask_sock这个模块&#xff0c;我的使用场景是&#xff1a;可以让数据多端实时同步。在游戏控制后台和游戏选手的ipad上都可以实时调整角色的技能和点数什么的&#xff0c;所以需要这样的一个功能来实现数据实时同步。 下面是最小的demo案例&#xff1a; from fla…

LoadLibraryEx调用dll时有未经处理的异常,发生访问冲突

0x000000000006A220 处的第一机会异常(在 testHFHZDll.exe 中): 0xC0000005: 执行位置 0x000000000006A220 时发生访问冲突。 0x000000000006A220 处有未经处理的异常(在 testHFHZDll.exe 中): 0xC0000005: 执行位置 0x000000000006A220 时发生访问冲突。 最近做一个测试&#…

[C++随笔录] stack queue使用

stack && queue使用 stackqueue题目训练 stack 栈的特点是 先进后出(first in last out) 我们可以看出, stack的接口相比 vector/string/list 的接口少的太多了 构造函数 && 容器适配器 容器适配器的含义: 首先, 适配器 — — 用户传数据进来, 我们用合适的…

mac安装python2

Python 2 于 2020 年 1 月 1 日宣布结束支持&#xff0c;包括 Homebrew 在内的许多项目和包管理器已经停止支持 Python 2。 如果现在你还要安装 Python 2&#xff0c;需要从 Python 官网下载安装包&#xff1a; 访问 Python 的发布页面。从页面底部找到 Python 2 的最后一个版…

DeepSpeed简单教程

DeepSpeed github地址、DeepSpeed 官网 、DeepSpeed API文档、huggingface DeepSpeed文档、知乎deepspeed入门教程、微软deepspeed博客示例代码&#xff1a;《Using DeepSpeed with HF&#x1f917; Trainer》、 BLOOM_LORA&#xff08;运行示例见《Running_Deepspeed》&#x…

C++标准模板(STL)- 输入/输出操纵符-(std::setbase,std::setfill)

操纵符是令代码能以 operator<< 或 operator>> 控制输入/输出流的帮助函数。 不以参数调用的操纵符&#xff08;例如 std::cout << std::boolalpha; 或 std::cin >> std::hex; &#xff09;实现为接受到流的引用为其唯一参数的函数。 basic_ostream::…

人工智能AI 全栈体系(七)

第一章 神经网络是如何实现的 神经网络不仅仅可以处理图像&#xff0c;同样也可以处理文本。由于处理图像讲起来比较形象&#xff0c;更容易理解&#xff0c;所以基本是以图像处理为例讲解的。 七、词向量 图像处理之所以讲起来比较形象&#xff0c;是因为图像的基本元素是像…

Ctfshow web入门 代码审计篇 web301-web310 详细题解 全

CTFshow 代码审计 web301 下载的附件的目录结构如下&#xff1a; 开题后界面&#xff0c;看见输入框&#xff0c;感觉是sql。 大概浏览一遍源码&#xff0c;我们可以发现在checklogin.php文件中有无过滤的SQL语句&#xff0c;SQL注入没得跑了。 这题SQL注入有三种做法。 方法一…

信息安全:网络物理隔离技术原理与应用.

信息安全&#xff1a;网络物理隔离技术原理与应用. 随着网络攻击技术不断增强&#xff0c;恶意入侵内部网络的风险性也相应急剧提高。满足内外网信息及数据交换需求&#xff0c;又能防止网络安全事件出现的安全技术就应运而生了&#xff0c;这种技术称为“物理隔离技术” 基本原…

使用Vue、ElementUI实现登录注册,配置axios全局设置,解决CORS跨域问题

目录 引言 什么是ElementUI&#xff1f; 步骤1&#xff1a;创建Vue组件用于用户登录和注册 1. 基于SPA项目完成登录注册 在SPA项目中添加elementui依赖 在main.js中添加elementui模块 创建用户登录注册组件 配置路由 修改项目端口并启动项目 静态页面展示图 步骤2&#x…

网络爬虫——urllib(1)

前言&#x1f36d; ❤️❤️❤️网络爬虫专栏更新中&#xff0c;各位大佬觉得写得不错&#xff0c;支持一下&#xff0c;感谢了&#xff01;❤️❤️❤️ 前篇简单介绍了什么是网络爬虫及相关概念&#xff0c;这篇开始讲解爬虫中的第一个库——urllib。 urllib&#x1f36d; …

Jenkins学习笔记4

配置构建流程&#xff1a; Jenkins任务创建&#xff1a; 1&#xff09;创建新任务&#xff1a; 把这个Accept first connection改成 No Validation。问题得到解决。 说明下&#xff0c;要确认下主分支的名称是master还是main。 构建触发器这块暂时没有需要配置的。 传输文件…

[FineReport]安装与使用(连接Hive3.1.2)

一、安装(对应hive3.1.2) 注&#xff1a;服务器的和本地的要同时安装。本地是测试环境&#xff0c;服务器的是生产环境 1、服务器安装 1、下载 免费下载FineReport - FineReport报表官网 向下滑找到 2、解压 [rootck1 /home/data_warehouse/software]# tar -zxvf tomcat…