当前位置: 首页 > news >正文

单元测试基本概念

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

一、 单元测试定义:

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

单元测试通常包括以下步骤:
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 函数在测试中的使用是为了创造一个可控、可重复、独立于外部环境的测试环境,以确保测试能够集中在被测试的代码上,而不受外部因素的影响。

相关文章:

单元测试基本概念

单元测试一般是开发来做的,但是因为业务需要也曾涉及过单元测试。目前就单元测试的基础概念做下总结。 一、 单元测试定义: 单元测试是软件开发中的一种测试方法,用于验证程序中的最小可测单元——即代码中的单个函数、方法或模块。单元测试…...

ECTouch 电商微信小程序 SQL注入漏洞复现(CVE-2023-39560)

0x01 产品简介 ECTouch是一款开源的电商系统,为中小企业提供最佳的新零售解决方案 0x02 漏洞概述 ECTouch 电商系统 /ectouch-main/include/apps/default/helpers/insert.php 文件中第285行的 insert_bought_notes 函数中,传入的 $arr[id] 参数未进行验证和过滤,导致未经…...

MCM备赛笔记——熵权法

Key Concept 熵权法是一种基于信息熵概念的权重确定方法,用于多指标决策分析中。信息熵是度量信息量的不确定性或混乱程度的指标,在熵权法中,它用来反映某个指标在评价过程中的分散程度,进而确定该指标的权重。指标的分散程度越高…...

vscode设置terminal的最大行数

今天跑代码出现一个问题,就是整个程序跑完,整个程序的输出信息过多,最开始输出的信息已经被vscode的缓存冲掉了,只能看到最后的一部分,具体的原因是vscode的terminal默认只能保存1000行的信息,所以如果想保…...

kafka hang 问题记录

参考文档 https://cloud.tencent.com/developer/article/1821477 9092端口 端口9092通常与Apache Kafka关联。 Kafka是一个开源的分布式事件流平台,用于构建实时的数据管道和流应用。 它能够处理任意大小的数据,以容错的方式处理数据流。 在默认配置…...

Jmeter-BeanShell脚本中for循环里面使用random随机数函数,每次生成的都一样

预想的是每次循环生成的随机数不一样,但实际使用Random函数生成的是重复的。 以下是部分原代码: List updateList new ArrayList(); for(Object o: fieldList){Map map new HashMap();map.put("id", o.get("id"));map.put("…...

高级编程。JavaScript中有哪些类型转换机制?

一、概述 前面我们讲到,JS中有六种简单数据类型:undefined、null、boolean、string、number、symbol,以及引用类型:object 但是我们在声明的时候只有一种数据类型,只有到运行期间才会确定当前类型 let x y ? 1 : …...

Linux系统下常用软件安装汇总,包括mysql,java,git,redis等

01.环境搭建 1.安装列表 MySQL 5.7.11 Java 1.8 Apache Maven 3.6 tomcat8.5 git Redis Nginx python docker 2.安装mysql 1.拷贝mysql安装文件到Linux的某个目录下 2.解压Linux安装包:tar -xvzf mysql-5.7.32-linux-glibc2.12-x86_64.tar.gz 3.进入解压后…...

【Linux】——期末复习题(一)

🎃个人专栏: 🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客 🐳Java基础:Java基础_IT闫的博客-CSDN博客 🐋c语言:c语言_IT闫的博客-CSDN博客 🐟MySQL&#xff1a…...

【论文阅读】Speech Driven Video Editing via an Audio-Conditioned Diffusion Model

DiffusionVideoEditing:基于音频条件扩散模型的语音驱动视频编辑 code:GitHub - DanBigioi/DiffusionVideoEditing: Official project repo for paper "Speech Driven Video Editing via an Audio-Conditioned Diffusion Model" paper&#…...

【华为 ICT HCIA eNSP 习题汇总】——题目集4

1、(多选)网络中出现故障后,管理员通过排查发现某台路由器的配置被修改了,那么管理员应该采取哪些措施来避免这种状况再次发生? A、管理员应该通过配置 ACL 来扩展只有管理员能够登录设备 B、管理员应该在路由的管理端…...

hadoop-common: CMake failed with error code 1

问题 在编译hadoop源码时遇到如下错误 hadoop-common: CMake failed with error code 1 看了这个错误表示一脸懵逼 排查 在mvn 的命令中增加 -X 和 -e mvn clean package -e -X -Pdist,native -DskipTests -Dmaven.javadoc.skip -Dopenssl.prefix/usr/local/bin/openssl 在…...

【面试】-科大讯飞日常实习面试

科大讯飞日常实习面试 提问的问题 面试30min,基本就是介绍项目以及提问java八股文,没有算法题 java保证线程安全的方法 需要根据具体场景选择合适的方法来保证线程安全。java中的异步请求如何实现你的SpringBoot项目怎么匹配在线人数请说出spring springMVC springboot之间的…...

MySQL 数据加密

MySQL 数据加密主要用于保护存储在数据库中的敏感信息,如用户密码、个人身份信息等。MySQL 提供了多种数据加密方法,主要包括: 对称加密: AES_ENCRYPT() 和 AES_DECRYPT() 函数:MySQL 支持使用高级加密标准&#xff08…...

风丘科技为您提供完整的ADAS测试方案

一 方案概述 随着5G通讯与互联网的快速发展,智能汽车和ADAS辅助系统的研究与发展在世界范围内也在如火如荼地进行。风丘科技紧跟时代脚步,经多年积累沉淀,携手整车厂与高校共同研发打造出了一套完整且适用于国内ADAS测试的系统方案。 | ADAS…...

深入理解Rust基本类型

文章目录 一、概述二、数值类型2.1、整数类型2.2、浮点类型2.3、数字运算2.4、位运算2.5、序列(Range)2.6、有理数和复数 三、字符、布尔、单元类型3.1、字符类型3.2、布尔类型(bool)3.3、单元类型 团队博客: 汽车电子社区 一、概…...

cloudflare加速方法

一、使用Cloudflare优速域名或IP,实现国内访问加速 二、使用境外CN2、GIA等直连联网的VPS:如华纳云、彩红云等(未测试) 三、页面托管方案: 四、cloudflare合作伙伴计划:自定义cdn节点、dnspod提供的dns解析…...

密码学学习笔记(二十四):TCP/IP协议栈

TCP/IP协议栈的基础结构包括应用层、传输层、网络层、数据链路层和物理层。 应用层 应用层位于TCP/IP协议栈的最顶层,是用户与网络通信的接口。这一层包括了各种高级应用协议,如HTTP(用于网页浏览)、FTP(用于文件传输…...

软件测试阶段简介_单元测试、集成测试、配置项测试、系统测试

文章目录 前言一、软件测试“V”模型二、单元测试三、集成测试四、配置项测试五、系统测试总结 前言 一般来说,按照软件的研制阶段划分,软件测试可分为单元测试、集成测试、配置项测试、系统测试等。本文将对上述各测试阶段进行逐一介绍。 一、软件测试…...

AcWing 1204.错误票据(读取未知个数数据的新方法)

[题目概述] 某涉密单位下发了某种票据,并要在年终全部收回。每张票据有唯一的ID号。全年所有票据的ID号是连续的,但ID的开始数码是随机选定的。 因为工作人员疏忽,在录入ID号的时候发生了一处错误,造成了某个ID断号,另…...

项目上线存在的缓存问题以及存在的debugger和console.log等问题

下载uglifyjs-webpack-plugin插件 在vue.config文件中进行配置 publicPath: process.env.NODE_ENV production ? ./ : /,outputDir: n-sim-ipc-manage-build,productionSourceMap: false,configureWebpack: config > {//打包文件增加hashconfig.output.filename js/[nam…...

均线和布林线这样的关系,WeTrade众汇实例这样使用

在后台经常有交易者咨询:“我可以用加权平均线或指数代替移动平均线吗?”理论上,任何平均值都适合绘制BB。在回答这个问题之前,为了稳妥起见,WeTrade众汇通过对各种均线对比分析,却得出这样结论:经典均线是构建参考点最简单、最准…...

C++中的区块链与加密货币开发

区块链和加密货币是当前科技领域中备受关注的热门话题。C作为一种高效的编程语言,被广泛应用于区块链和加密货币的开发。在本篇文章中,我将介绍C在区块链和加密货币开发中的重要性以及其应用方面。 区块链开发框架:C提供了多种区块链开发框架…...

【云略】2023年新茶饮行业社媒营销洞察报告

(因篇幅有限,推文仅展示部分内容) 2023新茶饮行业卷的比往年更厉害。 在整体市场环境快速增长的情况下,新茶饮品牌纷纷开始拼产品、抢联名、赶上市,搞下沉,整个行业进入到一个新的博弈阶段。 2023年蜜雪冰城…...

19. C++ static关键字

1. static关键字 不考虑类的情况 隐藏-所有不加static的全局变量和函数具有全局可见性,可以在其他文件中使用,加了之后只能在该文件所在的编译模块中使用,即内部连接默认初始化为0,包括未初始化的全局静态变量与局部静态变量&am…...

thinkphp6 模糊查找json下的字段值

写法: where(json的字段->json下的字段) sql生成json_extract(json的字段,$.json下的字段1.json下的字段2) 可以加上like where(‘‘json的字段->json下的字段, ‘like’, ‘%’. keyword .’%’) sql生成json_extract(json的字段,$.js…...

链表存数相加算法(leetcode第2题)

题目描述: 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这…...

旅游项目day07

目的地攻略展示 根据目的地和主题查询攻略 攻略条件查询 攻略排行分析 推荐排行榜:点赞数收藏数 取前十名 热门排行榜:评论数浏览数 取前十名 浏览数跟评论数差距过大,可设置不同权重,例如:将浏览数权重设置为0.3…...

java黑马学习笔记

数组 变量存在栈中&#xff0c;变量值存放在堆中。 数组反转 public class test{public static void main(String[] args){//目标&#xff1a;完成数组反转int[] arr {10,20,30,40,50};for (int i 0,j arr.length - 1;i < j;i,j--){int tep arr[j]; //后一个值赋给临时…...

WordPress后台底部版权信息“感谢使用 WordPress 进行创作”和版本号怎么修改或删除?

不知道各位WordPress站长在后台操作时&#xff0c;是否有注意到每一个页面底部左侧都有一个“感谢使用 WordPress 进行创作。”&#xff0c;其中WordPress还是带有nofollow标签的链接&#xff1b;而页面底部右侧都有一个WordPress版本号&#xff0c;如下图中的“6.4.2 版本”。…...