python基础8 单元测试
通过前面的7个章节,作者学习了python的各项基础知识,也学习了python的编译和执行。但在实际环境上,我们需要验证我们的代码功能符合我们的设计预期,所以需要结合python的单元测试类,编写单元测试代码。
Python有一个内置的unittest模块,我们可以使用它来进行单元测试。
基础用法
基本流程:
- 新建类,继承自unittest.TestCase
- 类的成员函数统一用test_开头,否则会无法识别和执行
- 通过调用unittest.main()来执行测试用例
简单的示例程序如下:
import unittest#新建类,继承自unittest.TestCase
#类的成员函数统一用test_开头,否则会无法识别和执行
#通过调用unittest.main()来执行测试用例class TestMath(unittest.TestCase):def test_add(self):self.assertEqual(1 + 1, 2)def test_subtract(self):self.assertEqual(3 - 2, 1)if __name__ == '__main__':unittest.main()
结果输出如下:
..
----------------------------------------------------------------------
Ran 2 tests in 0.000sOK
测试函数和类方法
对函数的单元测试:
import unittest#定义测试用的函数
def add(v1,v2):return v1+v2def subtract(v1,v2):return v1-v2class TestMath(unittest.TestCase):def test_add(self):#测试用例实现对函数的调用self.assertEqual(add(1, 1), 2)def test_subtract(self):#测试用例实现对函数的调用self.assertEqual(subtract(2, 3), -1)if __name__ == '__main__':unittest.main()
结果输出:
..
----------------------------------------------------------------------
Ran 2 tests in 0.000sOK
对类的单元测试:
在下面示例中,我们对函数和复用的Car类同时进行了单元测试。
import unittest#定义测试用的函数
def add(v1,v2):return v1+v2def subtract(v1,v2):return v1-v2#复用前期定义的Car类
class Car(object):__slots__ = ('_color', '_number')@propertydef color(self):return self._color@color.setterdef color(self,value):self._color = value@propertydef number(self):return self._number@number.setterdef number(self,value):self._number = value@number.deleterdef number(self):print('oops! number is deleted!')def func(self):print('car number: %d' % self._number)passclass TestAll(unittest.TestCase):def test_add(self):#测试用例实现对函数的调用self.assertEqual(add(1, 1), 2)def test_subtract(self):#测试用例实现对函数的调用self.assertEqual(subtract(2, 3), -1)def test_car_color(self):car = Car()car.color ="blue"self.assertEqual(car.color, "blue")#属性测试def test_car_property(self):car = Car()with self.assertRaises(AttributeError):value = car.engineif __name__ == '__main__':unittest.main()
结果输出:
....
----------------------------------------------------------------------
Ran 4 tests in 0.000sOK
测试套件和测试运行器
继承自unittest.TestCase的类,用test_开头的成员函数,可以称为一个测试用例。
使用测试套件的方法,可以自由的执行这些测试用例。如执行先后次序,部分执行等。
示例代码如下:
import unittest#定义测试用的函数
def add(v1,v2):return v1+v2def subtract(v1,v2):return v1-v2#复用前期定义的Car类
class Car(object):__slots__ = ('_color', '_number')@propertydef color(self):return self._color@color.setterdef color(self,value):self._color = value@propertydef number(self):return self._number@number.setterdef number(self,value):self._number = value@number.deleterdef number(self):print('oops! number is deleted!')def func(self):print('car number: %d' % self._number)passclass TestAll(unittest.TestCase):def test_add(self):#测试用例实现对函数的调用self.assertEqual(add(1, 1), 2)def test_subtract(self):#测试用例实现对函数的调用self.assertEqual(subtract(2, 3), -1)def test_car_color(self):car = Car()car.color ="blue"self.assertEqual(car.color, "blue")#属性测试def test_car_property(self):car = Car()with self.assertRaises(AttributeError):value = car.engineif __name__ == '__main__':# 创建测试套件suite = unittest.TestSuite()suite.addTest(TestAll('test_add'))#suite.addTest(TestAll('test_subtract'))suite.addTest(TestAll('test_car_property'))# 创建测试运行器runner = unittest.TextTestRunner()runner.run(suite) # 通过执行结果,我们可以看到仅执行了我们添加的两个测试用例
测试准备和清理
很多时候,我们在测试用例执行之前,需要做一些准备操作,如执行数据库相关测试用例之前,需要进行数据库连接;之后需要断开数据库连接。这种场景下,我们需要使用python单元测试类默认的setUp和tearDown方法。修改上面的代码,并测试。
import unittest#定义测试用的函数
def add(v1,v2):return v1+v2def subtract(v1,v2):return v1-v2#复用前期定义的Car类
class Car(object):__slots__ = ('_color', '_number')@propertydef color(self):return self._color@color.setterdef color(self,value):self._color = value@propertydef number(self):return self._number@number.setterdef number(self,value):self._number = value@number.deleterdef number(self):print('oops! number is deleted!')def func(self):print('car number: %d' % self._number)passclass TestAll(unittest.TestCase):def setUp(self):# 准备工作print("准备工作完成")def tearDown(self):# 结束后的工作print("结束清理工作完成")def test_add(self):#测试用例实现对函数的调用self.assertEqual(add(1, 1), 2)def test_subtract(self):#测试用例实现对函数的调用self.assertEqual(subtract(2, 3), -1)def test_car_color(self):car = Car()car.color ="blue"self.assertEqual(car.color, "blue")#属性测试def test_car_property(self):car = Car()with self.assertRaises(AttributeError):value = car.engineif __name__ == '__main__':# 创建测试套件suite = unittest.TestSuite()suite.addTest(TestAll('test_add'))#suite.addTest(TestAll('test_subtract'))suite.addTest(TestAll('test_car_property'))# 创建测试运行器runner = unittest.TextTestRunner()runner.run(suite)
结果输出:
准备工作完成
结束清理工作完成
.准备工作完成
结束清理工作完成
.
----------------------------------------------------------------------
Ran 2 tests in 0.001sOK
高级测试用法
条件测试
可以使用@unittest.skip关键字,来表示测试用例只有在满足特定条件下才执行。下面的示例中,我们使用关键字实现了一直跳过和条件跳过的功能。
@unittest.skip(reason)
Unconditionally skip the decorated test. reason should describe why the test is being skipped.
无条件跳过,需要输入填过的原因。
@unittest.skip("Always skip!")
@unittest.skipIf(condition, reason)
Skip the decorated test if condition is true.
条件满足时跳过。
@unittest.skipIf(mylib.__version__ < (1, 3),"not supported in this library version")
@unittest.skipUnless(condition, reason)
Skip the decorated test unless condition is true.
除此条件外,跳过。
@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
@unittest.expectedFailure
Mark the test as an expected failure or error. If the test fails or errors in the test function itself (rather than in one of the test fixture methods) then it will be considered a success. If the test passes, it will be considered a failure.
失败时,测试用例返回成功。
@unittest.expectedFailuredef test_fail(self):self.assertEqual(1, 0, "failed test")
exception unittest.SkipTest(reason)
This exception is raised to skip a test.
import unittest
import sys#定义测试用的函数
def add(v1,v2):return v1+v2def subtract(v1,v2):return v1-v2#复用前期定义的Car类
class Car(object):__slots__ = ('_color', '_number')@propertydef color(self):return self._color@color.setterdef color(self,value):self._color = value@propertydef number(self):return self._number@number.setterdef number(self,value):self._number = value@number.deleterdef number(self):print('oops! number is deleted!')def func(self):print('car number: %d' % self._number)passclass TestAll(unittest.TestCase):def setUp(self):# 准备工作print("准备工作完成")def tearDown(self):# 结束后的工作print("结束清理工作完成")@unittest.skip("啊!我被永久的跳过了")def test_add(self):#测试用例实现对函数的调用self.assertEqual(add(1, 1), 2)# windows系统下,执行此测试用例。还可以使用版本号版本等等@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")def test_subtract(self):#测试用例实现对函数的调用self.assertEqual(subtract(2, 3), -1)def test_car_color(self):car = Car()car.color ="blue"self.assertEqual(car.color, "blue")#属性测试def test_car_property(self):car = Car()with self.assertRaises(AttributeError):value = car.engineif __name__ == '__main__':# 创建测试套件suite = unittest.TestSuite()suite.addTest(TestAll('test_add'))suite.addTest(TestAll('test_subtract'))suite.addTest(TestAll('test_car_property'))# 创建测试运行器runner = unittest.TextTestRunner()runner.run(suite)
结果输出:
准备工作完成
结束清理工作完成
.准备工作完成
结束清理工作完成
.
----------------------------------------------------------------------
Ran 3 tests in 0.001sOK (skipped=1)
模拟对象
Python的unittest.mock模块提供了一种创建模拟对象的方法,我们可以用它来模拟外部的、不可控的因素。
import unittest
import sys
import datetime
#使用mock需要执行此引用
from unittest.mock import patch#定义测试用的函数
def add(v1,v2):return v1+v2def subtract(v1,v2):return v1-v2#复用前期定义的Car类
class Car(object):__slots__ = ('_color', '_number')@propertydef color(self):return self._color@color.setterdef color(self,value):self._color = value@propertydef number(self):return self._number@number.setterdef number(self,value):self._number = value@number.deleterdef number(self):print('oops! number is deleted!')def func(self):print('car number: %d' % self._number)def say(self):current_hour = datetime.datetime.now().hourif current_hour < 12:return "Good morning!"elif current_hour < 18:return "Good afternoon!"else:return "Good evening!"passclass TestAll(unittest.TestCase):def setUp(self):# 准备工作print("准备工作完成")def tearDown(self):# 结束后的工作print("结束清理工作完成")@unittest.skip("啊!我被永久的跳过了")def test_add(self):#测试用例实现对函数的调用self.assertEqual(add(1, 1), 2)# windows系统下,执行此测试用例。还可以使用版本号版本等等@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")def test_subtract(self):#测试用例实现对函数的调用self.assertEqual(subtract(2, 3), -1)def test_car_color(self):car = Car()car.color ="blue"self.assertEqual(car.color, "blue")#属性测试def test_car_property(self):car = Car()with self.assertRaises(AttributeError):value = car.engine@patch('datetime.datetime')# 注意此处多了一个mock_datetime参数def test_car_say(self, mock_datetime):car = Car()mock_datetime.now.return_value.hour = 9self.assertEqual(car.say(), "Good morning!")mock_datetime.now.return_value.hour = 15self.assertEqual(car.say(), "Good afternoon!")mock_datetime.now.return_value.hour = 20self.assertEqual(car.say(), "Good evening!")if __name__ == '__main__':# 创建测试套件suite = unittest.TestSuite()suite.addTest(TestAll('test_add'))suite.addTest(TestAll('test_subtract'))suite.addTest(TestAll('test_car_property'))suite.addTest(TestAll('test_car_say'))# 创建测试运行器runner = unittest.TextTestRunner()runner.run(suite)
结果输出:
备工作完成
结束清理工作完成
.准备工作完成
结束清理工作完成
.准备工作完成
结束清理工作完成
.
----------------------------------------------------------------------
Ran 4 tests in 0.002sOK (skipped=1)
相关文章:
python基础8 单元测试
通过前面的7个章节,作者学习了python的各项基础知识,也学习了python的编译和执行。但在实际环境上,我们需要验证我们的代码功能符合我们的设计预期,所以需要结合python的单元测试类,编写单元测试代码。 Python有一个内…...
【正点原子K210连载】第七十六章 音频FFT实验 摘自【正点原子】DNK210使用指南-CanMV版指南
第七十六章 音频FFT实验 本章将介绍CanMV下FFT的应用,通过将时域采集到的音频数据通过FFT为频域。通过本章的学习,读者将学习到CanMV下控制FFT加速器进行FFT的使用。 本章分为如下几个小节: 32.1 maix.FFT模块介绍 32.2 硬件设计 32.3 程序设…...
【杂记二】git, github, vscode等
一、前言 暂时空着... 二、git 2.1 可能的疑问 1. VSCode 项目名和 GitHub 仓库名是否需要一致? 不需要一致。 VSCode 项目名(也就是你本地的文件夹名字)和 GitHub 仓库名可以不一样。 Git 是一个分布式版本控制系统,它主要关…...
《基于Spring Boot+Vue的智慧养老系统的设计与实现》开题报告
个人主页:@大数据蟒行探索者 一、研究背景及国内外研究现状 1.研究背景 根据1982年老龄问题世界大会联合国制定的标准,如果一个国家中超过65岁的老人占全国总人口的7%以上,或者超过60岁的老人占全国总人口的10%以上,那么这个国家将被定义为“老龄化社会”[1]。 随着国…...
ModBus TCP/RTU互转(主)(从)|| Modbus主动轮询下发的工业应用 || 基于智能网关的串口服务器进行Modbus数据收发的工业应用
目录 前言 一、ModBus TCP/RTU互转(从)及应用|| 1.1 举栗子 二、ModBus TCP/RTU互转(主) 2.1 举栗子 三、ModBus 主动轮询 3.1 Modbus主动轮询原理 3.2 Modbus格式上传与下发 3.2.1.设置Modbus主动轮询指令 3.2.2 设…...
【设计模式】3W 学习法深入剖析创建型模式:原理、实战与开源框架应用(含 Java 代码)
3W 学习法总结创建型模式(附 Java 代码实战及开源框架应用) 创建型模式主要关注 对象的创建,旨在提高代码的可复用性、可扩展性和灵活性。本文采用 3W 学习法(What、Why、How),深入分析 五大创建型模式&am…...
Jobby、Quarkus 和 Spring Boot对比
Jobby、Quarkus 和 Spring Boot 是三种不同的 Java 框架,各自有不同的设计目标和适用场景。以下是对它们的详细对比: 1. 设计目标 框架设计目标Jobby轻量级的任务调度框架,专注于任务调度和执行。Quarkus面向云原生和 Kubernetes 的 Java 框…...
[代码规范]1_良好的命名规范能减轻工作负担
欢迎来到啾啾的博客🐱,一个致力于构建完善的Java程序员知识体系的博客📚,记录学习的点滴,分享工作的思考、实用的技巧,偶尔分享一些杂谈💬。 欢迎评论交流,感谢您的阅读😄…...
【HarmonyOS Next之旅】DevEco Studio使用指南(三)
目录 1 -> 一体化工程迁移 1.1 -> 自动迁移 1.2 -> 手动迁移 1.2.1 -> API 10及以上历史工程迁移 1.2.2 -> API 9历史工程迁移 1 -> 一体化工程迁移 DevEco Studio从 NEXT Developer Beta1版本开始,提供开箱即用的开发体验,将SD…...
冯・诺依曼架构深度解析
一、历史溯源:计算机科学的革命性突破 1.1 前冯・诺依曼时代 在 1940 年代之前,计算机领域呈现 "百家争鸣" 的格局: 哈佛 Mark I(1944):采用分离的指令存储与数据存储ENIAC(1946&a…...
gralloc1_perform具体在干什么
gralloc1_perform 会在特定场景下通过 ioctl 调用,执行 缓存 (cache) 管理 和 内存映射 操作,确保 CPU 和 GPU 之间的数据一致性。 📌 为什么需要对 cache 进行操作? 在 Android 系统中,CPU 和 GPU 通常共享 DDR 内存…...
安装配置Anaconda,配置VSCode
文章目录 Anaconda介绍下载Anaconda安装Anaconda换源创建一个新环境conda常用命令 VSCode环境配置 记录一下笔者收集的一些资料,不喜勿喷。 Anaconda介绍 Anaconda是一个用于科学计算的Python发行版,支持 Linux, Mac, Windows系统,提供了包管…...
【愚公系列】《高效使用DeepSeek》017-知识点思维导图生成
🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! 👉 江湖人称"愚公搬代码",用七年如一日的精神深耕技术领域,以"…...
【量化策略】网格交易策略
【量化策略】网格交易策略 🚀量化软件开通 🚀量化实战教程 技术背景与应用场景 网格交易策略是一种基于市场波动性的自动化交易方法,适用于震荡市场。它通过在预设的价格区间内设置多个买卖点,自动执行低买高卖的操作…...
C++ 语法之函数和函数指针
在上一章中 C 语法之 指针的一些应用说明-CSDN博客 我们了解了指针变量,int *p;取变量a的地址这些。 那么函数同样也有个地址,直接输出函数名就可以得到地址,如下: #include<iostream> using namespace std; void fun() …...
网络协议抓取与分析(SSL Pinning突破)
1. 网络协议逆向基础 1.1 网络协议分析流程 graph TD A[抓包环境配置] --> B[流量捕获] B --> C{协议类型} C -->|HTTP| D[明文解析] C -->|HTTPS| E[SSL Pinning突破] D --> F[参数逆向] E --> F F --> G[协议重放与模拟] 1.1.1 关键分析目标…...
蓝桥杯真题——洛谷Day13 找规律(修建灌木)、字符串(乘法表)、队列(球票)
目录 找规律 P8781 [蓝桥杯 2022 省 B] 修剪灌木 字符串 P8723 [蓝桥杯 2020 省 AB3] 乘法表 队列 P8641 [蓝桥杯 2016 国 C] 赢球票 找规律 P8781 [蓝桥杯 2022 省 B] 修剪灌木 思路:对某个特定的点来说有向前和向后的情况,即有向前再返回到该位置…...
【2025】基于Springboot + vue实现的毕业设计选题系统
项目描述 本系统包含管理员、学生、教师三个角色。 管理员角色: 用户管理:管理系统中所有用户的信息,包括添加、删除和修改用户。 配置管理:管理系统配置参数,如上传图片的路径等。 权限管理:分配和管理…...
JAVA并发编程 --- 补充内容
1 线程状态 1.1 状态介绍 当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。线程对象在不同的时期有不同的状态。那么Java中的线程存在哪几种状态呢?Java中的线程 状态被定义在了java.lang.Thread.State枚…...
ADB三个模块介绍
ADB(Android Debug Bridge)是 Android 开发中非常重要的工具,它由 3 个主要模块 组成,分别是 ADB Client(客户端)、ADB Server(服务端) 和 ADB Daemon(守护进程ÿ…...
【ArduPilot】Windows下使用Optitrack通过MAVProxy连接无人机实现定位与导航
Windows下使用Optitrack通过MAVProxy连接无人机实现定位与导航 配置动捕系统无人机贴动捕球配置无人机参数使用MAVProxy连接Optitrack1、连接无人机3、设置跟踪刚体ID4、校正坐标系5、配置IP地址(非Loopback模式)6、启动动捕数据推流 结语 在GPS信号弱或…...
qt 图像后处理的软件一
这是一个图像后处理软件刚刚,目前功能比较单一,后续会丰富常用的功能。 目前实现的功能有 1.导入图像 2图像可中心缩放(右上角放大缩小,按钮及滚轮双重可控)。 3.图像重置功能 软件界面如下。 代码放在我的资源里…...
Ardunio 连接OLED触摸屏(SSD1106驱动 4针 IIC通信)
一、准备工作 1、硬件 UNO R3 :1套 OLED触摸屏:1套 导线诺干 2、软件 arduino 二、接线 UNO R3OLED5VVCCGNDGNDA5SCLA4SDA 脚位如下图所示: Uno R3脚位图 触摸屏脚位图 查阅显示屏的驱动规格:通常显示屏驱动芯片有SSD1306,SH110…...
深度学习 第4章 数值计算和 Deepseek 的实践
第4章 数值计算和 Deepseek 的实践 章节概述 本章主要探讨了数值计算中的关键问题,这些问题在深度学习和机器学习中尤为重要。数值计算的核心挑战在于如何在有限的计算资源和精度限制下,高效且稳定地处理连续数学问题。本章首先讨论了溢出和下溢问题&a…...
【数据分享】2000—2024年我国省市县三级逐年归一化植被指数(NDVI)数据(年最大值/Shp/Excel格式)
之前我们分享过2000-2024年我国逐年的归一化植被指数(NDVI)栅格数据,该逐年数据是取的当年月归一化植被指数(NDVI)的年最大值。(可查看之前的文章获悉详情)!该数据来源于NASA定期发布…...
HW华为流程管理体系精髓提炼华为流程运营体系(124页PPT)(文末有下载方式)
资料解读:HW华为流程管理体系精髓提炼华为流程运营体系(124页PPT) 详细资料请看本解读文章的最后内容。 华为作为全球领先的科技公司,其流程管理体系的构建与运营是其成功的关键之一。本文将从华为流程管理体系的核心理念、构建…...
Linux中管理多版本Python总结
1. pyenv 管理多个 Python 版本 pyenv 是一个流行的工具,用于管理多个 Python 版本。它可以轻松安装、切换和管理不同版本的 Python。 1.1.安装 pyenv 1.1.1安装依赖 sudo apt-get update sudo apt-get install -y make build-essential libssl-dev zlib1g-dev…...
【系统架构设计师】操作系统 - 特殊操作系统 ③ ( 微内核操作系统 | 单体内核 操作系统 | 内核态 | 用户态 | 单体内核 与 微内核 对比 )
文章目录 一、微内核操作系统1、单体内核 操作系统2、微内核操作系统 引入3、微内核操作系统 概念4、微内核操作系统 案例 二、单体内核 与 微内核 对比1、功能对比2、单体内核 优缺点3、微内核 优缺点 一、微内核操作系统 1、单体内核 操作系统 单体内核 操作系统 工作状态 : …...
OpenBMC:BmcWeb添加路由4 设置method
设置method的方式与设置权限的方式类似: //http\routing\ruleparametertraits.hpp struct RuleParameterTraits {...self_t& methods(boost::beast::http::verb method){self_t* self = static_cast<self_t*>(this);std::optional<HttpVerb> verb = httpVerb…...
【RabbitMQ】RabbitMQ的基本架构是什么?包括哪些核心组件?
RabbitMQ基于AMQP协议实现,由多个核心组件组成,确保消息的可靠传递。 Rabbit的架构图: 1.RabbitMQ的基本架构: 1.核心组件: 1.Producer(生产者): 发送消息到RabbitMQ。 2.Exchange(交换机):接…...
