【单元测试】--编写单元测试
一、编写第一个单元测试
编写第一个单元测试通常包括以下步骤。以下示例以C#和NUnit为例:
- 创建测试项目:
- 在Visual Studio中,创建一个新的Class Library项目,这将是你的单元测试项目。
- 在解决方案资源管理器中,右键点击项目,选择 “管理 NuGet 包”,然后搜索并安装NUnit框架(NuGet包名:NUnit)。
- 编写被测代码:
- 在同一解决方案中,创建或打开你的C#项目,这将是你的被测项目。
- 在被测项目中,编写一个函数或方法,准备用于单元测试的代码。例如:
public class Calculator {public int Add(int a, int b){return a + b;} }
- 编写第一个单元测试:
- 回到你的单元测试项目,在该项目中,创建一个新的测试类,以测试被测代码中的方法。
- 在测试类中,使用
[Test]
特性标记你的测试方法,并使用断言来验证被测方法的行为。例如:
using NUnit.Framework;[TestFixture] public class CalculatorTests {[Test]public void Add_TwoIntegers_ReturnsSum(){// ArrangeCalculator calculator = new Calculator();// Actint result = calculator.Add(2, 3);// AssertAssert.AreEqual(5, result);} }
- 运行单元测试:
- 在Visual Studio中,打开测试资源管理器(Test Explorer),它会自动发现你的NUnit测试。
- 单击运行你的测试方法,或者使用Test Explorer中的运行按钮来执行所有测试。
- 检查测试结果:
- 在测试运行完成后,你将看到测试通过或失败的结果。
- 你可以查看测试报告,了解哪些测试通过,哪些失败。
这是一个简单的NUnit单元测试的示例,展示了如何创建测试项目,编写测试用例,运行测试以及查看测试结果。随着你的项目复杂性的增加,你可以编写更多的测试用例来确保你的代码按预期工作。
二、常见的断言函数
NUnit 提供了多种常见的断言函数,用于验证测试的期望结果是否与实际结果一致。以下是一些常见的断言函数示例:
-
Assert.AreEqual(expected, actual): 验证期望值与实际值相等。
Assert.AreEqual(5, result); // 期望值为 5
-
Assert.AreNotEqual(notExpected, actual): 验证期望值与实际值不相等。
Assert.AreNotEqual(7, result); // 期望值不等于 7
-
Assert.IsTrue(condition): 验证条件为真。
Assert.IsTrue(result > 0); // 验证 result 大于 0
-
Assert.IsFalse(condition): 验证条件为假。
Assert.IsFalse(result < 0); // 验证 result 不小于 0
-
Assert.IsNull(object): 验证对象为 null。
Assert.IsNull(myObject); // 验证 myObject 为 null
-
Assert.IsNotNull(object): 验证对象不为 null。
Assert.IsNotNull(myObject); // 验证 myObject 不为 null
-
Assert.Throws<ExceptionType>(delegate): 验证某个操作引发了特定类型的异常。
Assert.Throws<DivideByZeroException>(() => calculator.Divide(5, 0));
-
Assert.That(actual, constraint): 使用 NUnit 的约束条件(constraints)来验证实际值是否满足特定条件。这是一种非常灵活的断言方式。
Assert.That(result, Is.GreaterThan(0)); // 验证 result 大于 0
-
Assert.AreEqual(expected, actual, tolerance): 验证两个浮点数的相等性,允许一定的误差。
Assert.AreEqual(0.1, 0.2, 0.1); // 验证 0.1 和 0.2 在误差范围内相等
-
Assert.DoesNotThrow(delegate): 验证某个操作不引发任何异常。
Assert.DoesNotThrow(() => calculator.Add(2, 3)); // 验证 Add 操作不引发异常
这些是一些常见的 NUnit 断言函数示例。根据测试需求,你可以选择合适的断言函数来验证代码的行为和结果。不同的断言函数提供了不同的验证方式,以确保代码的正确性。请根据你的测试场景选择适当的断言函数。
三、Arrange, Act, Assert
在单元测试中,遵循"Arrange, Act, Assert"(AAA)模式是一种良好的实践,它有助于组织和编写清晰、可维护的测试用例。这种模式将测试用例分为三个主要部分,分别是:
- Arrange(准备): 在这个阶段,你准备测试的前提条件,包括设置对象、模拟依赖、初始化变量等。你的目标是为测试用例创建一个干净的起点状态,以确保测试独立于其他因素。在NUnit中,通常在测试方法的开头执行这些准备操作。
[Test] public void Test_AddTwoNumbers() {// ArrangeCalculator calculator = new Calculator();// Actint result = calculator.Add(2, 3);// AssertAssert.AreEqual(5, result); }
- Act(操作): 这一步中,你执行将要测试的操作或调用被测试的方法。在上述示例中,
calculator.Add(2, 3)
是"操作"步骤。 - Assert(断言): 在这个阶段,你验证操作的结果是否与期望值一致。你使用NUnit的断言函数来断言测试的实际结果。如果断言失败,测试将失败。
[Test] public void Test_AddTwoNumbers() {// ArrangeCalculator calculator = new Calculator();// Actint result = calculator.Add(2, 3);// AssertAssert.AreEqual(5, result); }
遵循AAA模式的优点包括:
- 可读性:每个测试用例都有明确的结构,易于阅读和理解。
- 易维护性:通过将准备、操作和断言步骤明确分开,更容易维护和修改测试用例。
- 独立性:每个测试用例都应该是独立的,不受其他测试用例的影响。
总之,"Arrange, Act, Assert"是编写NUnit单元测试的一种良好实践,有助于确保测试用例的可读性、可维护性和可靠性。
四、总结
编写第一个单元测试通常包括创建测试项目,编写被测代码,编写第一个单元测试,运行单元测试,检查测试结果。NUnit提供了常见的断言函数,用于验证测试的期望结果。遵循"Arrange, Act, Assert"(AAA)模式是单元测试的良好实践,它将测试用例分为准备、操作和断言三个部分,以提高可读性和可维护性。
相关文章:
【单元测试】--编写单元测试
一、编写第一个单元测试 编写第一个单元测试通常包括以下步骤。以下示例以C#和NUnit为例: 创建测试项目: 在Visual Studio中,创建一个新的Class Library项目,这将是你的单元测试项目。在解决方案资源管理器中,右键点…...

ES(elasticsearch) - 三种姿势进行分页查询
1. from size 浅分页 "浅"分页可以理解为简单意义上的分页。它的原理很简单,就是查询前20条数据,然后截断前10条,只返回10-20的数据。这样其实白白浪费了前10条的查询。 GET test_dev/_search {"query": {"bool&…...

AQS是什么?AbstractQueuedSynchronizer之AQS原理及源码深度分析
文章目录 一、AQS概述1、什么是AQS2、技术解释3、基本原理4、AQS为什么这么重要 二、AQS数据结构1、AQS的结构2、ReentrantLock与AbstractQueuedSynchronizer3、AQS的state变量4、AQS的队列5、AQS的Node(1)Node的waitStatus(2)属性…...
【数据库】函数处理(文本处理函数、日期和时间处理函数、数值处理函数)
函数处理数据 算术运算函数文本处理函数日期和时间处理函数数值处理函数 算术运算 操作符说明加-减*乘/除 e . g . e.g. e.g. 列出 Orders 表中所有每项物品的 id,数量 quantity,单价 item_price,总价 expanded_price(数量 * 单价…...

GEE案例——一个完整的火灾监测案例dNBR差异化归一化烧毁指数
差异化归一化烧毁指数 dNBR是"差异化归一化烧毁指数"的缩写。它是一种用于评估卫星图像中烧毁区域严重程度的遥感指数。dNBR值通过将火灾前的归一化烧毁指数(NBR)减去火灾后的NBR来计算得出。该指数常用于野火监测和评估。 dNBR(差异化归一化烧毁指数)是一种用…...

计算机算法分析与设计(20)---回溯法(0-1背包问题)
文章目录 1. 题目描述2. 算法思路3. 例题分析4. 代码编写 1. 题目描述 对于给定的 n n n 个物品,第 i i i 个物品的重量为 W i W_i Wi,价值为 V i V_i Vi,对于一个最多能装重量 c c c 的背包,应该如何选择放入包中的物品…...
什么是IO多路复用?Redis中对于IO多路复用的应用?
IO多路复用是一种高效的IO处理方式,它允许一个进程同时监控多个文件描述符(包括套接字、管道等),并在有数据可读或可写时进行相应的处理。这种机制可以大大提高系统的并发处理能力,减少资源的占用和浪费。 在Redis中&…...

NanoPC-T4 RK3399:DTS之io-domain,FAN
前言: 之后所有改动均是基于rk3399-evb.dts修改以满足NanoPC-T4功能正常。 NanoPC-T4开发板上有一片散热风扇,本章将讲述使风扇正常工作起来的多种方法。 一:硬件分析 GPIO4_C6/PWM1:实际控制风扇引脚,GPIO与PWM复用 输入高电平1:FAN2pin电路导通,风扇转动 输入低电…...
vue3+vite+ts项目使用jQuery
1、安装jQuery npm install --save jquery 2、安装声明文件 npm install --save types/jquery 3、在需要的文件中引入 import $ from jquery...
一起学数据结构(10)——排序
从本文开始,通过若干篇文章展开对于数据结构中——排序的介绍。 1. 排序的概念: 将一堆杂乱无章的数据,通过一定的规律顺序排列起来。即将一个无序序列排列成一个有序序(由小到大或者由大到小)的运算。 在数据的排序中…...

php 数组基础/练习
数组 练习在最后 数组概述 概述与定义 数组中存储键值对 数组实际上是一个有序映射 key-value,可将其当成真正的数组、列表(向量)、散列表、字典、集合、栈、队列等 数组中的元素可以是任意类型的数据对象(可以嵌套数组&#…...

Redbook Chapter 7: Query Optimization翻译批注
首先说明一下redbook上的几篇文章是做什么的。这几篇文章是通过几位作者对不同方面的论文进行阅读和筛选后,挑出其中具备代表性或者权威的论文来做分析,为读者提供阅读指导和建议,同时,也是对某个方面的论文进行高度的总结&#x…...

【分布式】大模型分布式训练入门与实践 - 04
大模型分布式训练 数据并行-Distributed Data Parallel1.1 背景1.2 PyTorch DDP1) DDP训练流程2)DistributedSampler3)DataLoader: Parallelizing data loading4)Data-parallel(DP)5)DDP原理解析…...

欧拉图相关的生成与计数问题探究
最近学了一波国家集训队2018论文的最后一个专题。顺便带上了一些我的注解。 先放一波这个论文 1.基本概念 欧拉图问题是图论中的一类特殊的问题。在本文的介绍过程中,我们将会使用一些图 论术语。为了使本文叙述准确,本节将给出一些术语的定义。 定义…...

CSS3属性详解(一)文本 盒模型中的 box-ssize 属性 处理兼容性问题:私有前缀 边框 背景属性 渐变 前端开发入门笔记(七)
CSS3是用于为HTML文档添加样式和布局的最新版本的层叠样式表(Cascading Style Sheets)。下面是一些常用的CSS3属性及其详细解释: border-radius:设置元素的边框圆角的半径。可以使用四个值设置四个不同的圆角半径,也可…...
小程序:如何合理规划分包使主包不超过2M
背景 做过小程序项目的同学应该都有这样的经历,项目做着做着,突然发现代码包的大小超过了 2M,小程序无法提审,然后痛苦的删文件改代码来减少包大小。 虽然我们也知道小程序给我们提供了分包的功能可以减少主包的大小,…...

迭代器的封装与反向迭代器
一、反向迭代器 在list模拟实现的过程中,第一次接触了迭代器的封装,将list的指针封装成了一个新的类型,并且以迭代器的基本功能对其进行了运算符重载 反向迭代器是对正向迭代器的封装,并且体现了泛型编程的思想,任意…...
PHP项目学习笔记-萤火商城https://www.yiovo.com/doc
萤火商城学习笔记 注意事项关于建表增加页面流程前台页面的数据列表数据下拉列表的数据 关于时间的处理前台界面数据处理 多年没有碰过php代码了,这个项目不错,想好好学习下,持续更新 注意事项 打开APP_DEBUG有些时候改了前台页面后&#x…...

我国有多少个港口?
港口是什么? 港口是海洋运输中不可或缺的重要设施之一,是连接陆路和水路运输的重要节点。港口通常是指位于沿海地区的水陆交通枢纽,是船舶停靠、装卸货物、储存物资和维修船只的场所。港口一般由码头、泊位、仓库、货场、客运站等设施组成&a…...

uniapp实现登录组件之外区域置灰并引导登录
实现需求 每个页面需要根据用户是否登录决定是否显示登陆组件,登录组件半屏底部显示,登录组件之外区域置灰,功能按钮点击之后引导提示登录.页面效果如下: 实现思路说明 设置登录组件背景颜色为灰色,将页面分成登录区域(底部)和非登陆区域(上面灰色显示部分), 置灰区域添加…...
yaffs2目录搜索上下文数据结构struct yaffsfs_dirsearchcontext yaffsfs_dsc[] 详细解析
1. 目录搜索上下文(Directory Search Context) struct yaffsfs_dirsearchcontext 是 YAFFS2 文件系统中用于 目录遍历操作 的核心数据结构,专门管理 readdir() 等目录操作的状态。 结构体定义(典型实现) struct yaf…...

vue3: bingmap using typescript
项目结构: <template><div class"bing-map-market"><!-- 加载遮罩层 --><div class"loading-overlay" v-show"isLoading || errorMessage"><div class"spinner-container"><div class&qu…...

Python-进程
进程 简介 操作系统分配资源的基本单位 创建 依赖 依赖模块 multiprocessing 中的 Process 语法 Process(group[,target[,name[,args[,kwargs]]]]) target:如果传递了函数的引用,这个子进程就执行这里的代码args:元组的方式传递&#x…...

数据湖是什么?数据湖和数据仓库的区别是什么?
目录 一、数据湖是什么 (一)数据湖的定义 (二)数据湖的特点 二、数据仓库是什么 (一)数据仓库的定义 (二)数据仓库的特点 三、数据湖和数据仓库的区别 (一&#…...
探索NoSQL注入的奥秘:如何消除MongoDB查询中的前置与后置条件
随着互联网技术的飞速发展,数据库作为信息存储与管理的核心,其安全性问题日益凸显。近年来,NoSQL数据库因其灵活性和高性能逐渐成为许多企业的首选,其中MongoDB以其文档存储和JSON-like查询语言在开发社区中广受欢迎。然而&#x…...

如何用AI高效运营1000+Tiktok矩阵账号
在当今数字化的时代,Tiktok 矩阵账号运营成为了众多企业和个人追求流量与变现的重要手段。然而,面对众多的账号管理,如何高效运营成为了关键。此时,AI 工具的出现为我们提供了强有力的支持。 一、Tiktok 矩阵账号的重要性 Tiktok…...
6.7本日总结
一、英语 复习默写list10list19,07年第3篇阅读 二、数学 学习线代第一讲,写15讲课后题 三、408 学习计组第二章,写计组习题 四、总结 本周结束线代第一讲和计组第二章,之后学习计网4.4,学完计网4.4之后开操作系…...

echarts使用graph、lines实现拓扑,可以拖动增加effect效果
options.js // import React from react // import * as echarts from echartsimport ./index.lessexport const useEchartsOptionFun ({ nodeDataList, getNodeLinksDataList, getLinesCoordsFun }) > {const option {title: {text: 拓扑关系图,top: top,left: center,}…...
Java 集合面试题 PDF 及常见考点解析与备考指南
为了帮助你更好地学习Java集合相关知识,我将围绕Java集合面试题展开,介绍常见的技术方案及应用实例。这些内容涵盖了集合框架的基本概念、常见集合类的特点与使用场景,以及在实际开发中可能遇到的问题及解决方案。 Java集合面试题࿱…...
华为OD机试_2025 B卷_数组去重和排序(Python,100分)(附详细解题思路)
题目描述 给定一个乱序的数组,删除所有的重复元素,使得每个元素只出现一次,并且按照出现的次数从高到低进行排序,相同出现次数按照第一次出现顺序进行先后排序。 输入描述 一个数组 输出描述 去重排序后的数组 用例 输入1,3,…...