python基础8 单元测试

通过前面的7个章节,作者学习了python的各项基础知识,也学习了python的编译和执行。但在实际环境上,我们需要验证我们的代码功能符合我们的设计预期,所以需要结合python的单元测试类,编写单元测试代码。

Python有一个内置的unittest模块,我们可以使用它来进行单元测试。

基础用法

基本流程:

  1. 新建类,继承自unittest.TestCase
  2. 类的成员函数统一用test_开头,否则会无法识别和执行
  3. 通过调用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(conditionreason)

Skip the decorated test if condition is true.

条件满足时跳过。

@unittest.skipIf(mylib.__version__ < (1, 3),"not supported in this library version")

@unittest.skipUnless(conditionreason)

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)

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

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

相关文章

【嵌入式学习】时钟 - 边缘触发锁存器

目录 ## 时钟 ## 带边缘触发的寄存器 ## 优化内存走线 ## 画16位的内存 ## 时钟 波特率&#xff1a;一分钟说几个字 clock统一计算机内部的节奏&#xff0c;clock频率越高cpu速度越快 触发&#xff1a;电压的突变&#xff1b;下降沿&#xff1a;高变低&#xff1b;上升沿…

Linux C/C++编程——线程

线程是允许应用程序并发执行多个任务的一种机制&#xff0c;线程参与系统调度。 系统调度的最小单元是线程、而并非进程。 线程包含在进程之中&#xff0c;是进程中的实际运行单位。一个线程指的是进程中一个单一顺序的控制流&#xff08;或者说是执行路线、执行流&#xff09;…

CAN通信转TCP/IP通信协议解析

背景&#xff1a;最近项目开发受限于开发版只有一路CAN口和多个CAN通信对象的帧ID一样&#xff0c;考虑采用转换模块将CAN通信转成TCP/IP通信&#xff0c;间接实现获取CAN报文数据的目的。 1. 转换模块协议 首先想到的是采购周立功他家的多路CAN通信转TCP/IP通信模块&#xf…

vue:组件的使用

Vue&#xff1a;组件的使用 1、什么是组件 1.1、传统方式开发的应用 一个网页通常包括三部分&#xff1a;结构&#xff08;HTML&#xff09;、样式&#xff08;CSS&#xff09;、交互&#xff08;JavaScript&#xff09;。在传统开发模式下&#xff0c;随着项目规模的增大&a…

强大的AI网站推荐(第一集)—— Devv AI

网站&#xff1a;Devv AI 号称&#xff1a;最懂程序员的新一代 AI 搜索引擎 博主评价&#xff1a;我的大学所有的代码都是使用它&#xff0c;极大地提升了我的学习和开发效率。 推荐指数&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x…

gradle-8.13

gradle-8.13 稍微看了下&#xff0c;基于Maven改造的 https://gradle.org/install/https://github.com/gradle/gradle-distributions/releaseshttps://github.com/gradle/gradle-distributions/releases/download/v8.13.0/gradle-8.13-all.zip https://github.com/gradle/gra…

网络安全——SpringBoot配置文件明文加密

XTHS&#xff1a;第一步、XTHS&#xff1a;第二步、XTHS&#xff1a;第三步、XTHS&#xff1a;第四步 &#xff01;就可以实现了。&#xff08;但是前提&#xff0c;你要先对你的文本进行加密&#xff0c;然后按照ENC(加密文本)&#xff0c;放到配置文件中&#xff09; 一、前言…

wsl2配置xv6全解(包括22.04Jammy)

文章目录 获取xv6源代码Ubuntu20.04 Version安装指令成功测试参考MIT2021年官方文档 24.04 Version安装指令成功测试参考MIT2024年官方文档 Ubuntu 22.04没有官方文档&#xff1f; 配置大体流程1. 卸载原本qemu&#xff08;如果之前安装了&#xff09;2. clone qemu官方源代码&…

【机器学习-分类算法】

比如将一张图片按尺寸识别分类为横向或者纵向两类就是二分类问题 设x轴为图像的宽、y轴为图像的高&#xff0c;那么把训练数据展现在图上就是这样的: 若增加更多的数据集有: 如果只用一条线将图中白色的点和黑色的点分开,那么: 分类的目的就是找到这条线,就可以根据点在线…

java项目之基于ssm的疫苗预约系统(源码+文档)

项目简介 疫苗预约系统实现了以下功能&#xff1a; 用户信息管理 负责管理系统用户的信息。 疫苗信息管理 负责管理疫苗的相关信息。 疫苗类型管理 负责管理不同种类疫苗的信息。 疫苗留言管理 负责管理用户关于疫苗的留言和反馈。 公告信息管理 负责发布和管理与疫苗相关…

游戏引擎学习第171天

回顾并计划今天的内容 昨天&#xff0c;我们在处理一项任务时暂停了&#xff0c;当时的目标非常清晰&#xff0c;但由于时间限制&#xff0c;我们将其分成了两个部分。我们首先完成了运行时部分&#xff0c;而今天要处理的是资产打包部分。这项任务涉及改进字体系统&#xff0…

跨平台RTSP高性能实时播放器实现思路

跨平台RTSP高性能实时播放器实现思路 目标&#xff1a;局域网100ms以内超低延迟 一、引言 现有播放器&#xff08;如VLC&#xff09;在RTSP实时播放场景中面临高延迟&#xff08;通常数秒&#xff09;和资源占用大的问题。本文提出一种跨平台解决方案&#xff0c;通过网络层…

Deepseek+飞书实现简历分析建议+面试题

步骤一&#xff1a;创建多维表格 点击云文档点击主页点击新建创建多维表格 步骤二&#xff1a;创建列 首先将多余的列进行删除 创建简历内容列&#xff0c;类型使用文本&#xff0c;目的是将简历内容复制进来 创建AI列&#xff1a;简历分析、简历建议、面试题 点击确定后&…

Linux基础开发工具--gdb的使用

目录 安装准备&#xff1a; 1. 背景 2. 开始使用 3. 做一个Linux第一个小程序&#xff0d;进度条 安装准备&#xff1a; 对于gdb的学习使用&#xff0c;为了方便大家学习&#xff0c;我建议大家先安装一个cgdb进行学习&#xff0c;这样方便观察操作与学习gdb。 用以下…

leetcode热题100道——两数之和

给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案&#xff0c;并且你不能使用两次相同的元素。 你可以按任意顺序返回答案。 示例 1…

某公司制造业研发供应链生产数字化蓝图规划P140(140页PPT)(文末有下载方式)

详细资料请看本解读文章的最后内容。 资料解读&#xff1a;某公司制造业研发供应链生产数字化蓝图规划 在当今制造业数字化转型的浪潮中&#xff0c;企业信息化建设成为提升竞争力的关键。本资料围绕 XX 公司的信息化建设展开&#xff0c;涵盖业务战略、信息化路线图、各领域系…

【总结篇】java多线程,新建线程有几种写法,以及每种写法的优劣势

java多线程 新建线程有几种写法,以及每种写法的优劣势 [1/5]java多线程 新建线程有几种写法–继承Thread类以及他的优劣势[2/5]java多线程-新建线程有几种写法–实现Runnable接口以及他的优劣势[3/5]java多线程 新建线程有几种写法–实现Callable接口结合FutureTask使用以及他的…

GB9706.1-2020附件J绝缘路径参考

下图为GB9706.1-2020绝缘路径示例图&#xff0c;附件J。 MOOP&#xff1a;对操作者的防护措施 MOPP&#xff1a;对患者的防护措施 1、保护接地外壳&#xff0c;网电源及次级电路与外壳之间。 网电源-外壳&#xff1a;1MOOP 次级电路-外壳&#xff1a;1MOOP 2、未保护接地外壳&…

基于springboot的教务系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要 这些年随着Internet的迅速发展&#xff0c;我们国家和世界都已经进入了互联网大数据时代&#xff0c;计算机网络已经成为了整个社会以及经济发展的巨大动能&#xff0c;各个高校的教务工作成为了学校管理事务的重要目标和任务&#xff0c;因此运用互联网技术来提高教务的…

大模型+知识图谱:赋能知识智能新升级

在大模型&#xff08;Large Language Model, LLM&#xff09;飞速发展的今天&#xff0c;如何把传统行业中沉淀多年的大量结构化与非结构化数据真正“用起来”&#xff0c;正成为推动智能化转型的关键一步。 找得到&#xff0c;看得懂&#xff0c;为何很难&#xff1f; 以制造…