单元测试该怎么写

单元测试对于开发人员来说很熟悉,各种语言都提供了单元测试的框架,用于自动化执行单元测试并生成测试报告。它通常提供了一组API和工具,使开发人员能够编写和运行测试用例,比较预期行为和实际行为之间的差异,并准确地识别和报告错误。常见的单元测试框架包括JUnit、pytest、Mocha、Jasmine等。通过使用单元测试框架,开发人员可以更快地识别和修复代码中的问题,从而提高代码的质量和可靠性。除此之外, 还有一些工具提供了从代码直接生成单元测试代码的功能。因为这些框架和工具, 以及实际开发过程中的资源和时程的关系导致单元测试的编写较少的状况, 形成了一些对单元测试的误解或者说片面的理解, 类似:

  • 单元测试是由开发人员编写的
  • 单元测试是从编写的代码出发的

本篇以软件开发流程的完整视角来看看单元测试究竟是什么? 怎么写? 由谁写?

单元测试的定义

单元测试是一种软件测试方法,用于测试程序的最小单元——函数、方法或类的功能、性能和正确性。它是一种自动化测试,通过编写测试代码来验证程序的各个单元是否符合预期,从而提高代码的质量和可靠性。单元测试的目的在于降低代码的缺陷率,减少维护成本和提高代码的可维护性。

从这个定义中可以看到单元测试的对象是函数、方法、功能、性能等,这个定义也容易引起单元测试就是从代码出发的误解。那么单元测试究竟是否应该从代码出发呢?

单元测试的出发点

单元测试(Unit Test, UT)代码通常是从系统的规格和设计中产生的,而非直接从代码中产生。这是因为单元测试的目的是验证软件的单元(如函数,方法等)是否按照预定的规格或设计来执行。
以下是产生单元测试的一般过程:

  1. 理解软件规格: 对系统或软件应用的需求和规格有深入的理解是编写单元测试的关键。需要知道每个函数或方法的预期行为,包括输入、输出和边界条件等。
  2. 设计测试用例: 根据了解的规格,设计测试用例来覆盖所有可能的场景。这包括正常流程,错误流程,边界条件等。测试用例应能映射到特定的需求或规格,从而确保系统满足这些规格。
  3. 编写测试代码: 用选择的测试框架实现设计好的测试用例。
  4. 执行测试: 执行编写的测试并观察结果。如果所有的测试都通过,表示函数或方法满足其规格。如果有测试未能通过,需要对代码进行调试或修复,然后再次进行测试。
  5. 评估代码覆盖率: 使用代码覆盖率工具评估测试用例对代码的覆盖程度,确保所有代码路径都被合适的测试用例覆盖。
  6. 回归测试: 在每次更改或添加新代码后,运行所有的测试用例以确保新的更改没有破坏现有的功能。

总的来说,单元测试应从规格和设计出发,帮助验证代码是否按预期执行。
那么是否单元测试就必须要从规格和设计出发呢? 答案其实也不是绝对的,也可以从代码出发编写单元测试。

从代码出发编写单元测试

从代码出发编写单元测试是一种可行的方法,它被称为“开发之后测试”(Test-After Development),与“测试驱动开发”(TDD,Test-Driven Development)相对。也就是首先编写代码,然后针对这些代码编写对应的单元测试。

这种方法的优点是,能够确保代码在写单元测试时已经完成了,并且有可能覆盖到写代码时没考虑到的异常情况。它还有助于发现代码设计上的问题,因为编写测试可能需要对代码进行重构以使其可测试。

然而,这种方法也有几个潜在的缺点。

  • 首先,可能滞后于写测试,尤其是在项目时间紧张或者开发者讨厌写测试的情况下。
  • 其次,在编写的代码中可能已经潜入了错误,而这种方式在代码编写完之后才开始测试,所以比测试驱动开发(TDD)发现问题要慢。
  • 最后,编写测试可能需要对代码进行重构以使其更易于测试,这可能会浪费一定的时间。

总结一下: 不论你选择哪一种方式,最重要的是尽可能保证代码的覆盖率,并确保每次代码的修改或添加都有对应的测试用例进行验证。同时,要知道没有一种方法是在所有情况下都适用的,应根据项目的具体需求和团队的开发流程灵活选择

TDD模式的单元测试谁来写?

在许多软件开发团队或项目中,同一个人会写代码和对应的单元测试,这是一种被称为"测试驱动开发"(Test-Driven Development,TDD)的策略。在TDD中,开发者首先会编写测试,然后编写满足这些测试的最小代码。这种策略有助于确保代码的质量,并驱使开发者设计可测试的代码。

但这并不是唯一的策略。在另一些团队或项目中,可能会有专门的角色如质量保证(Quality Assurance)工程师来编写测试,或者开发者之间互相编写彼此代码的测试,这被称为"互相测试"(Peer testing)。

以下是使用不同策略的一些优缺点:

  • 开发者自己编写单元测试

    • 优点:开发者对自己的代码最为了解,能够编写能全面覆盖代码的测试。
    • 缺点:开发者可能会陷入一种偏见,只测试他们认为会失败、并且在开发时已经考虑过的流程。也有可能过度依赖测试来编写代码,导致代码过于复杂。
  • 其他开发者或 QA 工程师编写单元测试

    • 优点:其他编写测试的开发者或者 QA 工程师可能更有可能发现代码中的缺陷或错误,因为他们对代码没有偏见。
    • 缺点:他们可能对被测试的代码没有那么了解,所以可能编写的测试覆盖不够全面。

以上为一般性的理论讲解。在实际项目中,选择哪种策略取决于项目的规模、团队的大小和结构、项目的时间线和预算,以及其他各种因素。

测试驱动开发示例

测试驱动开发(Test-Driven Development,TDD)强调首先编写单元测试,然后再编写能够让测试通过的代码。下面的例子将使用这种方法来实现一个简单的 “加法” 函数。

假设我们的需求是需要一个加法函数,它接受两个整数作为参数,并返回它们的和。

使用测试驱动开发,我们首先编写测试,下面是AdderTest.java的内容:

import org.junit.Test;
import static org.junit.Assert.assertEquals;public class AdderTest {@Testpublic void testAdder() {Adder adder = new Adder();assertEquals(4, adder.add(2, 2));}
}

这个时候,我们还没有编写 Adder 类和 add() 方法,所以测试会失败,接下来,我们编写 Adder 类和 add() 方法来使得测试通过,下面是Adder.java的内容:

public class Adder {public int add(int a, int b) {return a + b;}
}

现在,再次运行单元测试。这次,由于Adder类和其add()方法已经实现,并且实现正确,所以测试应该能够通过。

这就是一个简单的测试驱动开发的例子。首先编写了单元测试,然后再编写实现相应功能的代码以满足测试的要求。这样做的好处是确保我们的代码满足了需求,同时代码是可测试的。

BDD-行为驱动开发

在敏捷开发中, 我们经常会听到一个词BDD-行为驱动开发, BDD是什么呢? 和TDD又是什么关系呢?

行为驱动开发(BDD)是一种敏捷软件开发方法,旨在提高软件质量和产品交付时间。BDD强调开发人员、业务人员和测试人员之间的协作,以确保软件实现满足需求和期望。BDD的核心理念是以用户的行为和期望为中心来定义软件的功能和行为,从而更好地理解和满足用户需求。

BDD的核心步骤包括:

  1. 定义用户故事:开发人员通过与客户和利益相关者合作,定义用户故事,明确软件的功能和期望。
  2. 定义场景:开发人员和测试人员一起定义场景,描述用户在特定情况下使用软件的期望行为。
  3. 编写测试用例:开发人员编写测试用例,验证场景中描述的行为和期望。
  4. 实现功能:开发人员编写代码实现软件功能。
  5. 运行测试:测试人员运行测试用例,并确保软件满足用户故事和场景的期望。
  6. 重复迭代:在开发过程中,重复以上步骤,确保软件的功能和行为符合用户期望,并最终交付高质量的软件产品。

BDD非常适合敏捷开发方法,因为它能够帮助软件开发团队更快、更好地满足客户和利益相关者的需求,并确保软件能够按时交付。

BDD(行为驱动开发)和TDD(测试驱动开发)都是一种敏捷软件开发中的测试方法。两者的主要区别在于关注点不同。

  • TDD关注的是单元测试,即在编写代码之前先编写测试代码,通过测试代码来驱动开发过程。TDD的重点在于确保代码质量和代码覆盖率。

  • BDD则更关注整体行为和用户需求。BDD的核心是给出一个需求或者场景,通过编写测试代码来验证行为是否符合需求和用户期望。BDD更加强调通过测试用例来描述软件行为,同时更加注重开发过程中的沟通和协作。

两者之间的关系是:BDD是TDD的延伸和完善。BDD除了关注代码的质量和代码覆盖率,还更加注重用户需求和行为,通过测试用例来描述软件行为,从而更好地实现软件的设计和开发。
在这里插入图片描述



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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【已验证】微信小程序介绍及创建过程23.10.08

1、环境准备 开发微信⼩程序之前,必须要准备好相应的环境 1.1.注册账号 建议使用全新的邮箱,没有注册过其他小程序或者公众号的。访问注册⻚⾯,耐⼼完成注册即可。 1.2.获取APPID 由于登录,然后获取APPID 2.开发工具 下载地…

ElementUI结合Vue完成主页的CUD(增删改)表单验证

目录 一、CUD ( 1 ) CU讲述 ( 2 ) 编写 1. CU 2. 删除 二、验证 前端整合代码 : 一、CUD 以下的代码基于我博客中的代码进行续写 : 使用ElementUI结合Vue导航菜单和后台数据分页查询 ( 1 ) CU讲述 在CRUD操作中,CU代表创建(Create&#xff09…

设备搭建(waf、蜜罐、ids和ips)

文章目录 防火墙waf网闸蜜罐idsips 防火墙 DMZ区域叫非军事化区减,DMZ有web服务或者MySQL服务,从互联网到dmz的流量一般不拦截(因为需要互联网用户访问web服务),如果dmz沦陷,攻击者想要继续横向移动到内网…

Vue中实现自定义编辑邮件发送到指定邮箱(纯前端实现)

formspree里面注册账号 注册完成后进入后台新建项目并且新建表单 这一步完成之后你将得到一个地址 最后就是在项目中请求这个地址 关键代码如下: submitForm() {this.fullscreenLoading true;this.$axios({method: "post",url: "https://xxxxxxx…

什么是数据库锁(Lock)?有哪些类型的锁

数据库锁(Lock):保护数据完整性与并发性的关键 数据库锁(Lock)是在数据库管理系统中用于管理并发访问数据的重要机制。它们确保了多个用户或事务可以同时访问数据库,同时保护数据的完整性。在本文中&#…

7.wifi开发【智能家居:终】,实践总结:智能开关,智能采集温湿,智能灯。项目运行步骤与运行细节,技术归纳与提炼,项目扩展

一。项目运行步骤与运行细节 1.项目运行步骤(一定有其他的运行方式,我这里只提供一种我现在使用的编译方式) (1)项目运行使用软件与技术: 1.Virtual linux 使用这个虚拟机进行程序的编译 2.Makefile与shl…

【Navicat】win 10 / win 11:Navicat 15 安装完整教程(navicat 连接 mysql 出现 2059 报错问题解决)

目录 一、Navicat 连接 mysql 出现 2059 报错问题解决 二、Navicat 15 的下载 三、Navicat 15 的安装 四、Navicat 15 的使用 一、Navicat 连接 mysql 出现 2059 报错问题解决 之前使用的是完整版本 navicat 12,但是随着 MySQL 的升级,再连接 MySQL…

【SpringCloud】认识微服务

🐌个人主页: 🐌 叶落闲庭 💨我的专栏:💨 c语言 数据结构 javaEE 操作系统 Redis 石可破也,而不可夺坚;丹可磨也,而不可夺赤。 认识微服务 一、 服务架构演变1.1 单体架构…

库存管理与策略模式

库存管理是个难题,涉及到采购、销售、仓储、门店、网站订单各个环节,实物库存和系统库存很难保证完全一致,记得系统刚上线第一天,因为实物库存与导入系统的库存有差异,系统又做了限制系统库存必须大于0才允许销售普通订…

Spring的beanName生成器AnnotationBeanNameGenerator

博主介绍:✌全网粉丝4W,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验…

软件设计原则 1小时系列 (C++版)

文章目录 前言基本概念 Design Principles⭐单一职责原则(SRP) Single Responsibility PrincipleCode ⭐里氏替换原则(LSP) Liskov Substitution PrincipleCode ⭐开闭原则(OCP) Open Closed PrincipleCode ⭐依赖倒置原则(DIP) Dependency Inversion PrincipleCode ⭐接口隔离…

【Oracle】Oracle系列十九--Oracle的体系结构

文章目录 往期回顾前言1. 物理结构2. 内存结构2.1 SGA2.2 后台进程 3. 逻辑结构 往期回顾 【Oracle】Oracle系列之一–Oracle数据类型 【Oracle】Oracle系列之二–Oracle数据字典 【Oracle】Oracle系列之三–Oracle字符集 【Oracle】Oracle系列之四–用户管理 【Oracle】Or…

基于springboot实现人职匹配推荐管理系统演示【项目源码+论文说明】分享

基于springboot实现人职匹配推荐管理系统演示 摘要 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于人职匹配推荐系统当然也不能排除在外,随着网络技术的不断成熟,带动了…

ADuM1250 ADuM1251 模块 I2C IIC总线2500V电磁隔离 接口保护

功能说明: 1,2500V电磁隔离,2通道双向I2C; 2,支持电压在3到5.5V,最大时钟频率可达1000KHz; 3,将该隔离模块接入总线,可以保护主MCU引脚,降低I2C总线上的干…

【Java 进阶篇】HTML表格标签详解

HTML(Hypertext Markup Language)表格标签是在网页中用于创建表格的重要工具。表格是一种在网页上以行和列的方式组织和显示数据的有效方式。在本文中,我们将详细介绍HTML表格标签,包括如何创建表格、定义表头、单元格合并等内容。…

应用案例 | dataFEED OPC Suite为化工行业中的质量控制和成本节约提供数据集成方案

一 背景 在当今化工行业中,质量控制对于特种塑料供应商至关重要。一家国际性的特种塑料供应商在全球拥有五个生产基地,每个基地都运行着2-6台塑料挤出机。为了确保塑料质量,他们需要每两小时分析一次挤出样品——导致这项工作占用了较大的生…

WebGoat 靶场 JWT tokens 四 五 七关通关教程

文章目录 webGoat靶场第 四 关 修改投票数第五关第七关 你购买书,让Tom用户付钱 webGoat靶场 越权漏洞 将webgoat-server-8.1.0.jar复制到kali虚拟机中 sudo java -jar webgoat-server-8.1.0.jar --server.port8888解释: java:这是用于执行…

京东数据分析平台:2023年8月京东奶粉行业品牌销售排行榜

鲸参谋监测的京东平台8月份奶粉市场销售数据已出炉! 鲸参谋数据显示,8月份京东平台上奶粉的销售量将近700万件,环比增长约15%,同比则下滑约19%;销售额将近23亿元,环比增长约4%,同比则下滑约3%。…

【React】深入理解React组件状态State

目录 一、何为State二、如何定义State三、如何判断是否为State四、如何正确使用State1、用setState修改State2、State的更新是异步的①、代码示例 3、State更新会被合并①、组件状态例子②、当只需要修改状态title时,只需要将修改后的title传给setState③、React会合…

opencv图像的直方图,二维直方图,直方图均衡化

文章目录 opencv图像的直方图,二维直方图,直方图均衡化一、图像的直方图1、什么是图像的直方图:2、直方图的作用:3、如何绘制图像的直方图:(1)cv::calcHist()函数原型:英文单词 calc…