单元测试基础知识

软件测试基础知识必备之浅谈单元测试 阅读详情

前言

       本文是阅读了《单元测试之道》一书后的笔记,也是公司安排本人进行单元测试培训的材料,原文是一个Powerpoint,故修改了下,并针对Visual studio 2005自带的单元测试做的一个整理,将其奉献出来,目的是供需要了解和学习单元测试的朋友们阅读。如有错误望指出。

什么是单元测试?

单元测试是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确。通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为。例如,你可能把一个很大的值放入一个有序list 中去,然后确认该值出现在list 的尾部。或者,你可能会从字符串中删除匹配某种模式的字符,然后确认字符串确实不再包含这些字符了。

执行单元测试,是为了证明某段代码的行为确实和开发者所期望的一致。

为什么需要单元测试?

当编写项目的时刻,如果我们假设底层的代码是正确无误的,那么先是高层代码中使用了底层代码;然后这些高层代码又被更高层的代码所使用,如此往复。当基本的底层代码不再可靠时,那么必需的改动就无法只局限在底层。虽然你可以修正底层的问题,但是这些对底层代码的修改必然会影响到高层代码。于是,一个对底层代码的修正,可能会导致对几乎所有代码的一连串改动,从而使修改越来越多,也越来越复杂。从而使整个项目也以失败告终。

而单元测试的核心内涵:这个简单有效的技术就是为了令代码变得更加完美。

什么是断言

       Assertion(断言),它是一个简单的方法调用,用于判断某个语句是否为真。

例如:

public void IsTrue(bool condtion){

 if(!condition) abort();

}

应用则为:

int a=2;

IsTrue(a==2);

还可以编写更多的特定数据类型的断言。

计划你的单元测试

       当我们编写了一个如下的函数,它用于查找list中的最大值:static int Largest(int[] list);

所能想到的测试如下:

输入

预期结果

7,8,9

9

8,9,7

9

9,7,8

9

7,9,8,9

9

1

1

-9,-8,-7

-7

null

Exception

创建单元测试

       在解决方案资源管理器中右击某个测试项目,或在 Visual Studio 代码编辑器中,右击要测试的命名空间、类或方法并选择“创建单元测试”。



VsUnit
的各种断言

Assert

       在测试方法中,可以调用任意数量的 Assert 类方法,如 Assert.AreEqual()。Assert 类有很多方法可供选择,其中许多方法具有若干重载。

CollectionAssert

       使用 CollectionAssert 类可比较对象集合,也可验证一个或多个集合的状态。

StringAssert

       使用 StringAssert 类可对字符串进行比较。此类包含各种有用的方法,如 StringAssert.Contains、StringAssert.Matches 和 StringAssert.StartsWith。

AssertFailedException

       只要测试失败,就会引发 AssertFailedException 异常。如果测试超时,引发意外的异常,或包含生成了 Failed 结果的 Assert 语句,则该测试失败。

AssertInconclusiveException (无结果的)

       只要测试生成的结果为 Inconclusive,就会引发 AssertInconclusiveException。通常,向仍在处理的测试添加 Assert.Inconclusive 语句可指示该测试尚未准备好,不能运行。

UnitTestAssertException

       编写新的 Assert 异常类时使该类从基类 UnitTestAssertException 进行继承,可更方便地将异常标识为断言失败而非从测试或产品代码引发的意外异常。

ExpectedExceptionAttribute

       如果希望开发代码中的某方法引发异常,又想用测试方法来验证是否真的在该方法中引发了异常,则请用 ExpectedExceptionAttribute 属性来修饰测试方法。

       如:

        [TestMethod]

        [ExpectedException(typeof(ArgumentException),

           "userID 为 NULL 的异常检测.")]

        public void NullUserIdInConstructor()

        {

            LogonInfo logonInfo = new LogonInfo(null, "P@ss0word");

        }

单元测试的属性

       除了单元测试方法的 [TestMethod()] 属性及其包容类的 [TestClass()] 属性之外,可使用其他属性启用特定的单元测试功能。在这些属性中,最主要的属性有 [TestInitialize()] 和 [TestCleanup()]。使用标记有 [TestInitialize()] 的方法对将要在其中运行单元测试的环境的各个方面进行准备;这样做的目的在于为单元测试的运行建立已知的状态。例如,可以使用 [TestInitialize()] 方法复制、更改或创建测试中将要使用的某些数据文件。

       在运行完某个测试后,可通过标记有 [TestCleanup()] 的方法将环境返回到已知状态;这可能意味着需要删除文件夹中的文件,或将某个数据库返回到已知状态。例如,在测试了订单录入应用程序中使用的某个方法后,可将库存数据库重置为初始状态。此外,建议您在 [TestCleanup()] 或 ClassCleanup 方法中使用清除代码,而不要在终结器方法(~Constructor)中使用此代码。从终结器方法引发的异常不会被捕捉到,并且会导致无法预料的结果。

用于建立调用顺序的属性

对于程序集:

在加载程序集之后以及卸载程序集之前,将调用 AssemblyInitialize和 AssemblyCleanup。

       对于类 :

在加载类之后以及卸载类之前,将调用 ClassInitialize 和 ClassCleanup。

对于测试方法 :

在每个测试方法加载以及卸载之前,将调用TestInitialize 和TestCleanup

什么是VsUnit 的TestContext 类

       测试上下文类的属性存储有关当前测试运行的信息。例如,TestContext.DataRow 和 TestContext.DataConnection 属性包含测试用于数据驱动的单元测试的信息。

其他

用于对测试进行标识和排序的属性

测试配置类

用于生成报告的属性

用于专用访问器的类

测试哪些内容:Right-BICEP

Right----------结果是否正确?

B---------------是否所有的边界条件都是正确的?

I----------------能查一下反向关联吗?

C---------------能用其他手段交叉检查一下结果吗?

E---------------你是否可以强制错误条件发生?

P---------------是否满足性能要求?

RIGHT:结果是否正确

如果代码能运行正确,如何才知道它是正确的呢?

1、使用更明确的设计文档

2、真实环境数据

3、????

B:边界条件

       尽可能的至少各种特殊或者意外的情况,测试程序是否能正常工作,如:

l 完全伪造或者不一致的输入数据,如叫做“(*@Q!&#?±的文件。

l 格式错误的数据,如错误格式的邮件地址

l 空值或不完整的值

l 一些与意料中的合理值相去甚远的值,如年纪为10000

l 如果要求是一个不允许出现重复数值的list,但传入一个有重复数值的list

l 要求是一个有序的list,但传入一个无序的list

l 处理的顺序是错误的,或者与期望的次序不一致。如未登录系统就尝试打印。

B:边界条件的-CORRECT

Conformance(一致性)值是否和预期的一致

Ordering(顺序性)值是否应该的那样有序或者无序

Range(区间性)值是否位于合理范围

Reference(依赖性)代码是否引用了一些代码本身控制范围之外的资源

Existence(存在性)值是否存在(是否非空,非零,在集合中等等)

Cardinality(基数性)是否恰好有足够的值

Time(相对或绝对的时间性)所有事情的发生是否有序?是否在正确的时间?是否恰好及时?

I:检查反向关联

       通常一些结果可以使用反向的逻辑关系来验证它们是否正确,如:计算a*b的函数,测试方法如下:

Public void UsingInverse(){

 double x = MyMath.AB(4,4);

 Assert.AreEqual<double>(x,4*4);

}

C:使用其他手段实现交叉检查

计算一个结果可以存在多个算法,同一个算法可以使用稳定的版本来校验新改进的版本,如:

Public void UsingStd(){

    double number = 23214.01;

    double result1 = MyMath.旧方法(number1);

    double result2 = MyMath.新方法(number1);

    Assert.AreEqual<double>(result1,result2);

}

E:强制产生错误条件

       真实运行环境各种出乎意料的事情都可能发生,如断电,断网等等。在测试中模拟这些情况可以使用Mock对象来实现。

P:性能特性

    如数据采集的功能,在十个网站上进行采集工作很正常,那么在1000个网站上或更多的网站上进行采集它的速度如何?是否写个单元测试?

如何才是一个好的单元测试

好的测试应该具有的品质是:A-TRIP(合称)

Automatic 自动化

Thorough 彻底的

Repeatable可重复

Independent独立的

Professional 专业的

Automatic自动化

调用自动化

检查结果自动化

Thorough 彻底的

       测试所有可能会出现问题的情况,一个极端是,对于每行代码、代码可能到达的分支,每个可能抛出的异常等等,都可以作为测试的对象。另一个极端是,你仅仅测试最可能的情况---边界条件、残缺和畸形的数据等等。然而这些都基于项目需求的决策问题。

       这些所说的归纳为“代码覆盖率”。

Repeatable 可重复

       测试应该独立于所有其他的测试,而且必须独立于周围的环境。目标只有一个,就是测试应该能够以任意的顺序一次又一次的运行,并且产生相同的结果。如果结果不同,则存在BUG。

Independent 独立的

       编写测试时,确保一次只测试了一样东西,但并不表示一个TestMethod内只能使用一个Assert,而是一个测试函数应该专注于产品代码中的一个函数,或者组合起来并共同提供某个特性的一组函数。

Professional 专业的

       测试代码必须同产品代码相同的风格来编写。这意味着你需要抽取出共同且重复的代码,并把它们放到一个功能类之中,从而可以复用;单元测试的代码一样讲究------维护封装,DRY原则,降低耦合。

何时需要Mock对象

l 真实对象具有不可确定的行为(产生不可预测的结果,如股票的行情)

l 真实对象很难被创建(比如具体的web容器)

l 真实对象的某些行为很难触发(比如网络错误)

l 真实情况令程序的运行速度很慢

l 真实对象有用户界面

l 测试需要询问真实对象它是如何被调用的(比如测试可能需要验证某个回调函数是否被调用了)

l 真实对象实际上并不存在(当需要和其他开发小组,或者新的硬件系统打交道的时候,这是一个普遍的问题)

Mock对象的三个步骤

1.      原型

ClassA调用 ClassB的Method()

2.      使用一个接口来描述这个对象

ClassA 通过接口调用ClassB的Method

3.      以测试为目的,在mock对象中实现这个接口

 

 全文完

从零开始Cubemx配置STM32搭载freeRTOS以及lwip实现tcp网络通信(二) Cubemx配置LWIP,实现网络通信 阅读详情

相关推荐

数十个锂电池充放电电路,锂电池充放电芯片

关乎锂电池供电的产品,在锂电池上,需要三个电路系统:1,锂电池保护电路,2,锂电池充电电路,3,锂电池输出电路。 内容目录: 单节的锂电池保护电路单节为3.7V锂电池(也叫4.2V)和3.8V锂电池(也叫4.35V) 单节的锂电池充电电路即锂电池保护板 单节的锂电池输出电路锂电池转换稳压输出为:1.2V,3.3V,5V,12V等等 两节的锂电池保护电路两节串联7.4V锂电池(也叫8.4V) 两节的锂电池充电电路即两节锂电池保护板 两节...

kuakewei123的博客 1万+

编程防御之断言

都知道在编程过程中,最难受的就是调试错误

恶魔爱吃糖 348

SAP 深入理解库存

当 某个期间发生货物移动的时候,系统在更新mard数据的之前(这个表是实时更新的),会检查此笔业务过账期间和mard里对应记录的期间是否一致,也就是 看这是不是本期间第一笔移动。其二,我们不能保证这定期的作业的确定性,硬件维护、系统性能都可能使这预定的“时刻”出现偏差,如果某一次没能抓取该时刻的库存,对整个报表来说,是数据的缺失;中,当某一期间(Period)的第一项操作更新了物料数量或价值,则SAP系统会向表MBEWH写入一条记录,以第一项操作之前的余额、价格控制为标准。这对于业务数据量大的。

matinal 當冬夜漸暖 。公众号:matinal 3624

vs单元测试中Assert.Inconclusive() 表示一个未验证的测试

vs2012中每当自己添加一个单元测试的时候,会在测试方法后面自动添加一个: 其中,Assert.Inconclusive() 告诉了IDE,这个用例是一个未验证的测试,所以如果我们在程序中加入了自己的断言之后,就要注释或者删除这个语句,不然测试结果会显示这个用例为“已跳过”。而不是已运行。 转载于:https://www.cnblogs.com/hewenwu/p/3678216.html...

weixin_34194317的博客 362

第18届全国大学生智能汽车竞赛四轮车控制策略深度解析:从舵机PID到速度闭环

本文深度解析了第18届全国大学生智能汽车竞赛中四轮车的核心控制策略。从舵机PID方向控制的基础原理与机械校准入手,详细阐述了误差计算、PD控制等关键环节;进而深入探讨了基于编码器的速度闭环控制,包括增量式PI算法与速度决策逻辑。文章结合实战经验,提供了方向环与速度环的协同调参思路与避坑指南,旨在帮助参赛者构建稳定、高效的智能车控制系统。

potato的博客 464

沁恒CH32V30X学习笔记02--GPIO的使用教程及2次封装驱动

刚复位后,GPIO 口运行在初始状态,这时大多数 IO 口都是运行在状态所有的 GPIO 口都可以被配置外部中断输入通道,但一个外部中断输入通道最多只能映射到一个GPIO 引脚上,且外部中断通道的序号必须和 GPIO 端口的位号一致,,两方都是一对一的关系。复用功能。

Car12 706

Assert.IsTrue();Assert.AreEqual();Assert.IsNotNull()

断言方法说明:单元测试中,常用的断言方法介绍:Assert.AreEqual() 测试指定的值是否相等,如果相等,则测试通过;Assert.Inconclusive() 表示一个未验证的测试;Assert.IsTrue() 测试指定的条件是否为True,如果为True,则测试通过;Assert.IsFalse() 测试指定的条件是否为False,如果为False,则测试通过;...

weixin_34302798的博客 1万+

【Proteus仿真】用24C04与1602LCD设计的简易加密电子密码锁

【Proteus仿真】用24C04与1602LCD设计的简易加密电子密码锁

perseverance51博客 1122

ju 单元测试_单元测试基础知识

建议阅读时安装“微软雅黑”并开启ClearType效果前言本文是阅读了《单元测试之道》一书后的笔记,也是公司安排本人进行单元测试培训的材料,原文是一个Powerpoint,故修改了下,并针对Visual studio 2005自带的单元测试做的一个整理,将其奉献出来,目的是供需要了解和学习单元测试的朋友们阅读。如有错误望指出。什么是单元测试?单元测试是开发者编写的一小段代码,用于检验被测代码的一个...

weixin_39996908的博客 261

置顶必读(3) |《滚雪球学SpringBoot》· 高质量专栏介绍,你值得拥有!

《滚雪球学SpringBoot》 并不是普通的技术讲解合集,它是专为开发者精心设计的系统化学习路径。通过不断“滚动学习”,我们将带领你从基础入门到高阶应用,从理解每一行代码到设计和优化大规模分布式系统,最终帮助你成长为一位精通 spring架构 的工程师。

**My Coding Family** 15万+

超临界二氧化碳再热再压缩布雷顿循环建模与先进控制

超临界二氧化碳布雷顿循环建模与先进控制研究 本文研究了超临界二氧化碳再热再压缩布雷顿循环系统的建模与控制。通过MATLAB/Simscape构建了包含压缩机、透平、回热器等关键组件的动态模型,并设计了基于模型预测控制(MPC)和自抗扰控制(ADRC)的多层控制策略。系统采用转速控制的压缩机、阀门开度控制的透平,以及可变热源加热器,实现了全动态分析。研究结果表明,MPC与ADRC混合控制方案相较于传统PID控制,功率超调降低至0.9%,效率波动控制在±0.08%,扰动恢复时间缩短至12秒。

AI的内部世界的博客 342

计算机基础知识单元一测试题,计算机基础知识单元测试A卷

计算机基础知识单元测试A卷时间:100分钟 分值:150分姓名 班级 分数一、单项选择题(本大题共35小题,每小题3分,共105分。下列各题的A、B、C、D四个选项中,只有一个选项是正确的,请将正确答案的字母写在指定的位置)1.现代电子计算机的设计理念是源于1946年6月( )博士提出的“存储程序”理论设计出来的。A.莫克利 B...

weixin_35901475的博客 791

互联网人提高效率必备软件合集

很多的时候我们解决不了问题,只是因为没有找到对的工具,实际上,很多好的工具就在那里,只是你不用而已。这点上,信息壁垒是一个很大的原因,因此我希望兄伙伴们多出去走走,不要只是局限在一个圈层;

zhonglunshun的专栏 3484

[Test] 单元测试艺术(1) 基础知识

单元测试不是软件开发的新概念,在1970年就一直存在,屡屡被证明是最理想的方法之一。 本系列将分成3节: 单元测试基础知识 打破依赖,使用模拟对象,桩对象,测试框架 创建优秀的单元测试 本节索引: 单元测试与集成测试 测试驱动开发 UnitTest和NUnit 第一个单元测试 命名规范 单元测试与集成测试 单元测试几乎总是基于框架来写的...

denaoderenhuan8776的博客 153

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

【单元测试】--基础知识

单元测试是软件开发中的一种测试方法,用于验证代码中的单个组件(通常是函数、方法或类)是否按预期工作。它旨在隔离和测试代码的最小单元,以确保其功能正确,提高代码质量和可维护性。单元测试通常是自动化的,重点在于发现和修复潜在问题,从而减少后续开发阶段的错误和成本。本文总结了单元测试的基本概念、重要性、好处、挑战以及基本原则。单元测试是软件开发中的关键实践,可以提高代码质量、减少错误成本,同时需要遵循一些基本原则以确保有效性和可维护性。

喵叔 743

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

单元测试基础知识 (一)

1 背景 测试是开发的一个非常重要的方面,可以在很大程度上决定一个应用程序的命运。良好的测试可以在早期捕获导致应用程序崩溃的问题,但较差的测试往往总是导致故障和停机。 单元测试用于测试各个代码组件,并确保代码按照预期的方式工作。单元测试由开发人员编写和执行。大多数情况下,使用JUnit或TestNG之类的测试框架。测试用例通常是在方法级别写入并通过自动化执行。 ...

abigail2015的博客 289

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

上一篇: c#正则表达式收藏
下一篇: 关于Generating user instances in SQL Server is disabled. Use sp_configure 'user instances enabled' to generate user instances的错误
Csdbfans
博客等级 码龄18年 73粉丝 33原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值