单元测试基本概念

单元测试一般是开发来做的,但是因为业务需要也曾涉及过单元测试。目前就单元测试的基础概念做下总结。

一、 单元测试定义:

单元测试是软件开发中的一种测试方法,用于验证程序中的最小可测单元——即代码中的单个函数、方法或模块。单元测试的目的是检查单元(代码的最小功能单元)是否按照涉及预期进行工作。

单元测试通常包括以下步骤:
1、选择单元: 确定要测试的单元,这可以是一个函数、方法、类或模块。
2、编写测试用例: 为选定的单元编写测试用例,这些用例包括了各种可能的输入情况,以及对应的期望输出。
3、运行测试: 执行测试用例,将实际输出与期望输出进行比较。
4、断言: 在测试中使用断言来验证代码的行为。如果实际输出与期望输出不匹配,测试将失败,表明代码存在问题。
5、重复测试: 对不同的输入情况重复执行测试,确保代码在各种条件下都能正确运行。
6、集成到构建流程: 将单元测试集成到软件构建(编译和打包)流程中,以便在每次更改代码时自动运行测试。
说明:我实际测试的项目经历是PLC的单元测试,因为涉及到硬件部分的交互,需要有一些MOCK函数(桩函数)用于模拟真实硬件设备的行为,基本步骤如上。对于像Python(unittest、pytest )、C#(Nunit)、Java(Junit)等语言都有自己的单元测试框架,这些框架也同样可以用来搭建软件UI或者接口自动化测试框架。

二、单元测试的覆盖度:

在单元测试中,覆盖度指标用于衡量测试用例对代码的覆盖程度。以下是一些常见的覆盖指标及其简要说明,以及一些示例:

1、语句覆盖(Statement Coverage):
定义: 表示测试用例执行时是否覆盖了被测试代码中的每个语句。
示例:

def example_statement_coverage(x):if x > 0:result = "Positive"else:result = "Non-positive"return result

一个测试用例,比如 example_statement_coverage(5),可以满足语句覆盖,因为它覆盖了 if 和 else 分支中的每一行代码。
特别说明:在看到这个例子的时候我也很困惑,为什么example_statement_coverage(5)一个用例就满足了语句覆盖。原因是:对于循环结构,只要循环体内的语句被执行到,就满足语句覆盖。对于异常处理,只要 try 块内的语句被执行到,就满足语句覆盖。总体而言,语句覆盖关注的是在测试中每一条语句都至少被执行一次,不论是在条件语句、循环结构、异常处理,还是其他控制流结构中。
语句覆盖是一种最基本的覆盖度度量,确保你的测试至少触发了被测代码的每一行。

2、条件覆盖(Branch Coverage):
定义: 表示测试用例是否覆盖了每个条件语句的每个可能分支。
示例:

def example_branch_coverage(x, y):if x > 0 and y > 0:result = "Both positive"elif x > 0 or y > 0:result = "At least one is positive"else:result = "Both non-positive"return result

三个测试用例,比如 example_branch_coverage(3, 0) 和 example_branch_coverage(-2, 5),example_branch_coverage(0, 0) 分别覆盖了不同的条件分支,可以满足条件覆盖。

3、路径覆盖(Path Coverage):
定义: 表示测试用例是否覆盖了被测试代码中的每个可能执行路径。
示例: 如果一个函数有三个条件语句,每个条件语句有两个分支,总共有2^3=8条路径,路径覆盖率为75%表示测试用例覆盖了其中6条路径。

def example_path_coverage(x, y):if x > 0:if y > 0:result = "Both positive"else:result = "Only x is positive"else:result = "x is non-positive"return result

两个测试用例,比如 example_path_coverage(3, 2) 和 example_path_coverage(-1, 5),分别覆盖了不同的执行路径,可以满足路径覆盖。

4、判定覆盖(Decision Coverage):
定义: 与条件覆盖类似,但强调的是对每个条件语句的“真”和“假”两种情况的覆盖。
示例: 如果一个条件语句有两个分支,判定覆盖率为100%表示测试用例覆盖了条件语句的真和假两种情况。

def example_decision_coverage(x, y):if x > 0:result = "x is positive"if y > 0:result = "y is positive"return result

5、函数覆盖(Function Coverage):
定义: 表示测试用例是否覆盖了被测试函数的所有可能调用。
示例: 如果一个类有多个方法,函数覆盖率为60%表示测试用例覆盖了其中3个方法。

这些覆盖指标通常由专业的代码覆盖工具提供,可以帮助开发人员评估测试用例的质量和代码的覆盖情况。在实践中,常常会结合多个指标来综合评估测试的全面性。然而,注意到高覆盖率并不能保证代码的完全正确性,因此在设计测试用例时,还需要考虑具体的业务逻辑、边界条件和异常情况。

三、单元测试最可能发现的问题是什么

单元测试主要用于验证程序中的独立单元(通常是函数、方法或类)是否按照预期工作。在进行单元测试时,最常发现的问题包括:

逻辑错误(Logical Errors): 单元测试经常能够发现代码中的逻辑错误,例如条件语句、循环或算法中的错误。这些错误可能导致程序在特定条件下产生不正确的结果。

边界条件问题(Boundary Conditions): 单元测试通常有助于发现在输入达到边界条件时可能出现的问题。例如,当输入**为零、**负值或非常大的值时,程序是否能够正确处理。

异常处理问题(Exception Handling): 单元测试可以验证代码在面对异常情况时是否能够正确地抛出、捕获和处理异常。这包括输入错误、文件不存在等情况。

状态问题(State Issues): 对于有状态的对象或类,单元测试可以揭示对象状态不一致或不正确的问题。确保在对象的生命周期中状态的变化符合预期。

性能问题(Performance Issues): 虽然单元测试主要关注功能性,但有时也可以用于发现一些性能方面的问题,例如代码中的性能瓶颈或不必要的计算。

接口问题(Interface Issues): 当单元测试一个函数或方法时,可能会发现与其他组件的接口不匹配或不一致的问题。这可以包括参数类型、返回类型或异常的处理。

依赖问题(Dependency Issues): 单元测试时,有时会揭示代码依赖的外部组件、库或服务不正确、不可用或不稳定的情况。

内存泄漏(Memory Leaks): 尽管单元测试通常不是主要用于检测内存问题的工具,但在某些情况下,它们可能会帮助发现一些简单的内存泄漏问题。

通过这些问题的发现,单元测试有助于提高代码的可靠性和质量,确保每个独立单元在各种情况下都能按照预期执行。然而,要全面确保系统质量,还需要其他层次的测试,如集成测试和系统测试。

四、单元测试什么情况下需要用到MOCK函数

MOCK 函数通常在软件测试中使用,其主要目的是模拟真实的函数或对象,以便在测试过程中隔离和控制代码的行为。以下是一些情况下可能需要使用 MOCK 函数的例子:

硬件交互的模拟: 当代码与外部硬件设备进行交互,例如传感器、执行器、外部服务等,为了在没有实际硬件设备的情况下进行测试,可以使用 MOCK 函数模拟这些设备的行为。

依赖项隔离: 当被测试的代码依赖于外部库、服务、数据库等,为了隔离这些依赖项,可以使用 MOCK 函数替代真实的依赖项,确保测试的焦点仅在被测试的代码上。

异常条件的模拟: 在测试中,有时需要模拟一些特殊的条件,例如网络错误、文件不存在等异常情况,以确保代码能够正确地处理这些异常。

提高测试速度: 有时候,真实的依赖项可能比较复杂或耗时,使用 MOCK 函数可以提高测试的运行速度,因为它们是在内存中模拟的,而不涉及真实的外部调用。

测试边界条件: MOCK 函数可以用于测试代码在边界条件下的行为,例如极大或极小的输入值、特殊字符等。

避免副作用: 在某些情况下,真实的函数可能会引起一些副作用,例如修改数据库、发送电子邮件等,使用 MOCK 函数可以避免不必要的副作用。

总的来说,MOCK 函数在测试中的使用是为了创造一个可控、可重复、独立于外部环境的测试环境,以确保测试能够集中在被测试的代码上,而不受外部因素的影响。

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

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

相关文章

SAP PI/PO 运行ESR报错:无法验证证书,将不执行该应用程序

java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: OCSP 运行ESR报错 解决方案: 1. 打开控制面板,找到JAVA 这个时候就可以正常打开ESR了

如何在CentOS 7 中搭建Python 3.0 环境

1、下载 通过https://www.python.org/ftp/python/下载Python安装包,这里下载Python-3.10.9.tgz; 2、上传 借助MobaXterm等工具将Python安装包上传至/opt目录; 3、解压 将JDK压缩文件解压至/opt目录:tar -xvf /opt/Python-3.1…

【从浅到深的算法技巧】构造函数,实例方法

1.2.3抽象数据类型的实现 和静态方法一样,我们也需要使用Java的类(class )实现抽象数据类型并将所有代码放入一个和类名相同并带有java扩展名的文件中。文件的第一部分语句会定义表示数据类型的值的实例变量。它们之后是实现对数据类型的值的操作的构造函数和实例方…

2024年第二届“华数杯”国际大学生数学建模竞赛 (A题 MCM)| 废水扩散分析 |数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时,你是否曾经感到茫然无措?作为2022年美国大学生数学建模比赛的O奖得主,我为大家提供了一套优秀的解题思路,让你轻松应对各种难题。 让我们来看看华数杯的A题! 完整内容可以在文章末…

zabbix-api

一、API官方文档 https://www.zabbix.com/documentation/4.0/zh/manual/api https://www.zabbix.com/documentation/5.0/zh/manual/api 二、使用示例 1、获取zabbix token curl -s -X POST http://192.168.1.1/zabbix/api_jsonrpc.php -H Content-Type: application/json-rp…

机器学习算法 - 马尔可夫链

马尔可夫链(Markov Chain)可以说是机器学习和人工智能的基石,在强化学习、自然语言处理、金融领域、天气预测、语音识别方面都有着极其广泛的应用 > The future is independent of the past given the present 未来独立于过去&#xff…

java SECS管理系统 将逐步推出 SECS 客户端(Passive) 管理系统 SECS快速开发平台 springboot secs开发平台

SECS管理系统 这是一套SECS客户端(Passive),可以直接连接PLC设备,支持Modbus、三菱MC、欧姆龙Fine、OPC-UA、西门子S7设备等通信。 企业已经有了EAP软件,但是设备没有SECS通信功能,这时候可以使用这套框架,直接连接设备&#xff…

GEE使用

【GEE】Google Earth Engine(GEE)注册详细教程&无需教育邮箱-CSDN博客 数据下载代码 // Map the function over 3 months of data and take the median. // Load Landsat-8 surface reflectance data.var landsat8 ee.ImageCollection("LAND…

vue3和vue2区别

响应式区别 在 Vue 2 中,使用了 Object.defineProperty 来实现数据的响应式。它通过逐个定义对象属性的方式来进行数据的劫持和监听。这种方式存在一些限制,例如无法监听新增的属性,需要使用 Vue 提供的 $set 方法来实现响应式。此外&#x…

使用composer生成的DMG和PKG格式软件包有何区别

在使用Composer从包源构建软件包时候,有两种不同类型的包:PKG和DMG。你知道两者之间的区别吗? 以及如何选取吗? 每种格式都有各自的优势具体取决于软件包的预期用途以及用于部署软件包的工具。下面我们来了解一下PKG和DMG格式的区别和用途。…

STM32面试体验和题目

目录 一、说一下你之前的工作主要干了什么? 二、stm32有关的知识点 1.stm32的外设有哪一些 2.你的毕业论文的项目里面是怎么设计的 三,C语言的考察 1.写一个结构体(结构体的内容自由发挥) 2.写一个指针型的变量 3.结构体是…

C语言经典算法之快速排序算法

目录 前言 1. 快速排序简介 2. 快速排序的基本原理 2.1 选择基准元素 2.2 分割操作 2.3 递归排序 3. C语言中的快速排序实现 4. 总结 前言 快速排序算法可以分为两部分来看: 第一部分:将枢轴元素移动到最终位置 第二部分:分别处理枢轴…

Python密码本连接wifi

有时候我们会忘记自己的Wi-Fi密码,或者需要连接某个Wi-Fi网络以满足合法需求。本文将介绍如何使用Python编程语言编写一个简单的连接Wi-Fi的程序。 一、密码本准备 在进行wifi猜测时,其实就是列出各种可能的密码,用来尝试去访问目标wifi&…

Vue + JS + tauri 开发一个简单的PC端桌面应用程序

Vue JS tauri 开发一个简单的PC端桌面应用程序 文章目录 Vue JS tauri 开发一个简单的PC端桌面应用程序1. 环境准备1.1 安装 Microsoft Visual Studio C 生成工具[^2]1.2 安装 Rust[^3] 2. 使用 vite 打包工具创建一个 vue 应用2.1 使用Vite创建前端Vue项目2.2 更改Vite打包…

计算机毕业设计 基于Java的美食信息推荐系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…

vi/vim 编辑器 --基本命令

1 vi/vim编辑器介绍 vi 是visual interface 的简称,是Linux中最经典的文本编辑器 vim是vi的加强版。兼容了vi的所有指令,不仅能编辑文本,而且具有shell程序编辑的功能,可以通过不同颜色的字体辨别语法的正确性,极大…

轻松识别Midjourney等AI生成图片,开源GenImage

AIGC时代,人人都可以使用Midjourney、Stable Diffusion等AI产品生成高质量图片,其逼真程度肉眼难以区分真假。这种虚假照片有时会对社会产生不良影响,例如,生成公众人物不雅图片用于散播谣言;合成虚假图片用于金融欺诈…

支持华为GaussDB数据库的免费开源ERP:人力资源管理解决方案概述

开源智造所推出的Odoo SuperPeople数字化解决方案将HR和薪资数据与财务、项目规划、预算和采购流程连接起来,消除了多套系统给企业带来的信息孤岛问题。 ——复星集团 人力资源中心 高经理 一种更具吸引力、更有洞察力的人员管理方式 什么是开源智造Odoo的人力资源…

【Vue】后端返回文件流,前端预览文件

let date;request({url: this.$route.query.url,method: get,responseType: blob,}).then(resp > {date respthis.path window.URL.createObjectURL(new Blob([resp], {type: "application/pdf"}))}).catch((e) > {//旧版本浏览器下的blob创建对象window.Blo…

centos系统设置runlevel为5

在 CentOS 系统中,可以使用以下步骤将运行级别(runlevel)设置为 5: 1. 打开终端或 SSH 连接到 CentOS 服务器。 2. 以 root 用户身份登录。 3. 运行以下命令来编辑 /etc/inittab 文件: shell sudo vi /etc/inittab…