单元测试该怎么写

news2024/11/26 21:37:43

单元测试对于开发人员来说很熟悉,各种语言都提供了单元测试的框架,用于自动化执行单元测试并生成测试报告。它通常提供了一组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 {
    @Test
    public 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.coloradmin.cn/o/1070562.html

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

相关文章

Android Studio新建项目缓慢解决方案

关于Android Studio2022新建项目时下载依赖慢的解决方案 起因解决方案gradle下载慢解决方案kotlin依赖下载慢解决方案 结尾 起因 新建Android Studio项目时,常会因为网络问题导致部分依赖下载缓慢,其中gradle和kotlin最拖慢进度。 解决方案 gradle下载…

Spring源码解析——IOC属性填充

正文 doCreateBean() 主要用于完成 bean 的创建和初始化工作,我们可以将其分为四个过程: 最全面的Java面试网站 createBeanInstance() 实例化 beanpopulateBean() 属性填充循环依赖的处理initializeBean() 初始化 bean 第一个过程实例化 bean在前面一篇…

四位十进制数字频率计VHDL,仿真视频、代码

名称:四位十进制数字频率计VHDL,quartus仿真 软件:Quartus 语言:VHDL 代码功能: 使用直接测频法测量信号频率,测频范围为1~9999Hz,具有超量程报警功能 演示视频:四位十进制数字频…

5分钟理解什么是卷积的特征提取

大家好啊,我是董董灿。 卷积算法之所以重要,关键在于其提取特征的能力。 5分钟入门卷积算法中提到,卷积模仿的就是人眼识图的过程,以“感受野”的视角去扫描图片,从而获取不同区域的图片信息。 在这一过程中&#x…

Scratch3.0下载

通俗易懂,直接上链接 链接:https://pan.baidu.com/s/1n-QFEQWT8im8BHQu1wIjtg?pwd1016 提取码:1016

高级IO(Linux)

高级IO 五种IO模型高级IO重要概念同步通信 vs 异步通信阻塞 vs 非阻塞 非阻塞IOfcntl实现函数SetNoBlock轮询方式读取标准输入 I/O多路转接之select初识selectselect函数原型参数解释参数timeout取值关于fd_set结构关于timeval结构函数返回值三级目录 理解select执行过程socket…

多功能频率计周期/脉宽/占空比/频率测量verilog,视频/代码

名称:多功能频率计周期、脉宽、占空比、频率测量verilog 软件:Quartus 语言:Verilog 代码功能: 多功能频率计,可测量信号的周期、脉冲宽度、占空比、频率,语言为verilog,quartus软件设计仿真…

B (1089) : DS单链表--合并

Description 假定两个单链表是递增有序,定义并实现以下函数,完成两个单链表的合并,继续保持递增有序 int LL_merge(ListNode *La, ListNode *Lb) Input 第1行先输入n表示有n个数据,接着输入n个数据 第2行先输入m表示有M个数据…

扭线机控制

扭线机属于线缆加工设备,线缆加工设备种类非常多。有用于网线绞合的单绞,双绞机等,有关单绞机相关算法介绍,大家可以查看专栏相关文章,有详细介绍,常用链接如下: 线缆行业单绞机控制算法&#…

MySQL命令行中文乱码问题

MySQL命令行中文乱码问题: 命令行界面默认字符集是gbk,若字符集不匹配会中文乱码或无法插入中文。 解决办法:执行set names gbk; 验证: 执行命令show variables like ‘char%’;查看默认字符集。 创建数据库设置字符集utf8&…

Nginx详细学习记录

1. Nginx概述 Nginx是一个轻量级的高性能HTTP反向代理服务器,同时它也是一个通用类型的代理服务器,支持绝大部分协议,如TCP、UDP、SMTP、HTTPS等。 1.1 Nginx基础架构 Nginx默认采用多进程工作方式,Nginx启动后,会运行…

多线程锁-synchronized字节码分析

从字节码角度分析synchronized实现 javap -c(v附加信息) ***.class 文件反编译 synchronized同步代码块 >>>实现使用的是monitorenter和monitorexit指令 synchronized普通同步方法 >>>调用指令将会检查方法的ACC_SYNCHRONIZED访问标志是否被设置&#xf…

HTTPS工作过程,国家为什么让http为什么要换成https,Tomcat在MAC M1电脑如何安装,Tomcat的详细介绍

目录 引言 一、HTTPS工作过程 二、Tomcat 在访达中找到下载好的Tomcat文件夹(这个要求按顺序) zsh: permission denied TOMCAT的各部分含义: 引言 在密码中一般是:明文密钥->密文(加密) &#xff…

ubuntu 安装postgresql,增加VECTOR向量数据库插件 踏坑详细流程

PGSQL安装,删除,运行,修改密码流程 Ubuntu18.04安装与配置postgresql含远程连接教程(含踩坑记录)_sudo apt-get install postgresql-CSDN博客 详细安装流程以上博客,自己也记录下 安装vector扩展连接 声明…

微服务学习(十):安装Maven

微服务学习(十):安装Maven 1、下载Maven 官网下载 2、将下载后的资源包上传到服务器 3、解压资源包并安装 tar -zxvf apache-maven-3.9.5-bin.tar.gz4、配置环境变量 vi /etc/profileexport MAVEN_HOME/home/maven/apache-maven-3.9.5 …

如何部署一个高可用高并发的电商平台

假设我们已经有了一个特别大的电商平台,这个平台应该部署在哪里呢?假设我们用公有云,一般公有云会有多个位置,比如在华东、华北、华南都有。毕竟咱们的电商是要服务全国的,当然到处都要部署了。我们把主站点放在华东。…

汇编语言是怎么一回事?

汇编语言基础 汇编指令和机器码的区别 数据的表示 各类汇编指令 数据传送和算法运算 位运算 条件分支指令 函数调用 字符串处理 流水线和指令调度 流水线实现指令级并行 编译器指令调度 CPU乱序与投机执行 汇编器将汇编语言翻译成 CPU 可以执行的机器码&#xff0c…

【软考】9.1 顺序表/链表/栈和队列

《线性结构》 顺序存储和链表存储 每个元素最多只有一个出度和一个入度,表现为一条线状链表存储结构:每个节点有两个域,即数据,指针域(指向下一个逻辑上相邻的节点) 时间复杂度:与其数量级成正…

OpenCV防抖实践及代码解析笔记

视频防抖是指用于减少摄像机运动对最终视频的影响的一系列方法。摄像机的运动可以是平移(比如沿着x、y、z方向上的运动)或旋转(偏航、俯仰、翻滚)。 正如你在上面的图片中看到的,在欧几里得运动模型中,图像…

分布式文件系统HDFS(林子雨慕课课程)

文章目录 3. 分布式文件系统HDFS3.1 分布式文件系统HDFS简介3.2 HDFS相关概念3.3 HDFS的体系结构3.4 HDFS的存储原理3.5 HDFS数据读写3.5.1 HDFS的读数据过程3.5.2 HDFS的写数据过程 3.6 HDFS编程实战 3. 分布式文件系统HDFS 3.1 分布式文件系统HDFS简介 HDFS就是解决海量数据…