关于“Python”的核心知识点整理大全27
目录
10.5 小结
第11 章
测试代码
11.1 测试函数
name_function.py
函数get_formatted_name()将名和姓合并成姓名,在名和姓之间加上一个空格,并将它们的 首字母都大写,再返回结果。为核实get_formatted_name()像期望的那样工作,我们来编写一个 使用这个函数的程序。程序names.py让用户输入名和姓,并显示整洁的全名: names.py
11.1.1 单元测试和测试用例
11.1.2 可通过的测试
test_name_ function.py
11.1.3 不能通过的测试
name_ function.py
11.1.4 测试未通过时怎么办
name_function.py
往期快速传送门👆(在文章最后):
感谢大家的支持!欢迎订阅收藏!专栏将持续更新!
10.5 小结
在本章中,你学习了:如何使用文件;如何一次性读取整个文件,以及如何以每次一行的方 式读取文件的内容;如何写入文件,以及如何将文本附加到文件末尾;什么是异常以及如何处理 程序可能引发的异常;如何存储Python数据结构,以保存用户提供的信息,避免用户每次运行程 序时都需要重新提供。
在第11章中,你将学习高效的代码测试方式,这可帮助你确定代码正确无误,以及发现扩展 现有程序时可能引入的bug。
第11 章
测试代码
11.1 测试函数
要学习测试,得有要测试的代码。下面是一个简单的函数,它接受名和姓并返回整洁的姓名:
name_function.py
def get_formatted_name(first, last):"""Generate a neatly formatted full name."""full_name = first + ' ' + lastreturn full_name.title()
函数get_formatted_name()将名和姓合并成姓名,在名和姓之间加上一个空格,并将它们的 首字母都大写,再返回结果。为核实get_formatted_name()像期望的那样工作,我们来编写一个 使用这个函数的程序。程序names.py让用户输入名和姓,并显示整洁的全名: names.py
from name_function import get_formatted_name
print("Enter 'q' at any time to quit.")
while True:first = input("\nPlease give me a first name: ")if first == 'q':breaklast = input("Please give me a last name: ")if last == 'q':breakformatted_name = get_formatted_name(first, last)print("\tNeatly formatted name: " + formatted_name + '.')
这个程序从name_function.py中导入get_formatted_name()。用户可输入一系列的名和姓,并 看到格式整洁的全名:
Enter 'q' at any time to quit.
Please give me a first name: janis
Please give me a last name: joplinNeatly formatted name: Janis Joplin.
Please give me a first name: bob
Please give me a last name: dylanNeatly formatted name: Bob Dylan.
Please give me a first name: q
从上述输出可知,合并得到的姓名正确无误。现在假设我们要修改get_formatted_name(), 使其还能够处理中间名。这样做时,我们要确保不破坏这个函数处理只有名和姓的姓名的方式。 为此,我们可以在每次修改get_formatted_name()后都进行测试:运行程序names.py,并输入像 Janis Joplin这样的姓名,但这太烦琐了。所幸Python提供了一种自动测试函数输出的高效方式。 倘若我们对get_formatted_name()进行自动测试,就能始终信心满满,确信给这个函数提供我们 测试过的姓名时,它都能正确地工作。
11.1.1 单元测试和测试用例
Python标准库中的模块unittest提供了代码测试工具。单元测试用于核实函数的某个方面没 有问题;测试用例是一组单元测试,这些单元测试一起核实函数在各种情形下的行为都符合要求。 良好的测试用例考虑到了函数可能收到的各种输入,包含针对所有这些情形的测试。全覆盖式测 试用例包含一整套单元测试,涵盖了各种可能的函数使用方式。对于大型项目,要实现全覆盖可 能很难。通常,最初只要针对代码的重要行为编写测试即可,等项目被广泛使用时再考虑全覆盖。
11.1.2 可通过的测试
创建测试用例的语法需要一段时间才能习惯,但测试用例创建后,再添加针对函数的单元测 试就很简单了。要为函数编写测试用例,可先导入模块unittest以及要测试的函数,再创建一个继承unittest.TestCase的类,并编写一系列方法对函数行为的不同方面进行测试。 下面是一个只包含一个方法的测试用例,它检查函数get_formatted_name()在给定名和姓时 能否正确地工作:
test_name_ function.py
import unittest
from name_function import get_formatted_name
1 class NamesTestCase(unittest.TestCase):"""测试name_function.py"""def test_first_last_name(self):"""能够正确地处理像Janis Joplin这样的姓名吗?"""
2 formatted_name = get_formatted_name('janis', 'joplin')
3 self.assertEqual(formatted_name, 'Janis Joplin')
unittest.main()
首先,我们导入了模块unittest和要测试的函数get_formatted_ name()。在1处,我们创建 了一个名为NamesTestCase的类,用于包含一系列针对get_formatted_name()的单元测试。你可随 便给这个类命名,但最好让它看起来与要测试的函数相关,并包含字样Test。这个类必须继承 unittest.TestCase类,这样Python才知道如何运行你编写的测试。
NamesTestCase只包含一个方法,用于测试get_formatted_name()的一个方面。我们将这个方 法命名为test_first_last_name(),因为我们要核实的是只有名和姓的姓名能否被正确地格式化。 我们运行test_name_function.py时,所有以test_打头的方法都将自动运行。在这个方法中,我们 调用了要测试的函数,并存储了要测试的返回值。在这个示例中,我们使用实参'janis'和'joplin' 调用get_formatted_name(),并将结果存储到变量formatted_name中(见2)。
在3处,我们使用了unittest类最有用的功能之一:一个断言方法。断言方法用来核实得到 的结果是否与期望的结果一致。在这里,我们知道get_formatted_name()应返回这样的姓名,即 名和姓的首字母为大写,且它们之间有一个空格,因此我们期望formatted_name的值为Janis Joplin。为检查是否确实如此,我们调用unittest的方法assertEqual(),并向它传递formatted_ name和'Janis Joplin'。代码行self.assertEqual(formatted_name, 'Janis Joplin')的意思是说: “将formatted_name的值同字符串'Janis Joplin'进行比较,如果它们相等,就万事大吉,如果它 们不相等,跟我说一声!”
代码行unittest.main()让Python运行这个文件中的测试。运行test_name_function.py时,得 到的输出如下:
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
第1行的句点表明有一个测试通过了。接下来的一行指出Python运行了一个测试,消耗的时 间不到0.001秒。最后的OK表明该测试用例中的所有单元测试都通过了。 上述输出表明,给定包含名和姓的姓名时,函数get_formatted_name()总是能正确地处理。 修改get_formatted_name()后,可再次运行这个测试用例。如果它通过了,我们就知道在给定Janis Joplin这样的姓名时,这个函数依然能够正确地处理。
11.1.3 不能通过的测试
测试未通过时结果是什么样的呢?我们来修改get_formatted_name(),使其能够处理中间名, 但这样做时,故意让这个函数无法正确地处理像Janis Joplin这样只有名和姓的姓名。 下面是函数get_formatted_name()的新版本,它要求通过一个实参指定中间名:
name_ function.py
def get_formatted_name(first, middle, last):
"""生成整洁的姓名"""full_name = first + ' ' + middle + ' ' + lastreturn full_name.title()
这个版本应该能够正确地处理包含中间名的姓名,但对其进行测试时,我们发现它再也不能 正确地处理只有名和姓的姓名。这次运行程序test_name_function.py时,输出如下:
1 E
======================================================================
2 ERROR: test_first_last_name (__main__.NamesTestCase)
----------------------------------------------------------------------
3 Traceback (most recent call last):File "test_name_function.py", line 8, in test_first_last_nameformatted_name = get_formatted_name('janis', 'joplin')
TypeError: get_formatted_name() missing 1 required positional argument: 'last'
----------------------------------------------------------------------
4 Ran 1 test in 0.000s
5 FAILED (errors=1)
其中包含的信息很多,因为测试未通过时,需要让你知道的事情可能有很多。第1行输出只 有一个字母E(见1),它指出测试用例中有一个单元测试导致了错误。接下来,我们看到 NamesTestCase中的test_first_last_name()导致了错误(见2)。测试用例包含众多单元测试时, 知道哪个测试未通过至关重要。在3处,我们看到了一个标准的traceback,它指出函数调用 get_formatted_name('janis', 'joplin')有问题,因为它缺少一个必不可少的位置实参。 我们还看到运行了一个单元测试(见4)。最后,还看到了一条消息,它指出整个测试用例 都未通过,
因为运行该测试用例时发生了一个错误(见5)。这条消息位于输出末尾,让你一眼 就能看到——你可不希望为获悉有多少测试未通过而翻阅长长的输出。
11.1.4 测试未通过时怎么办
测试未通过时怎么办呢?如果你检查的条件没错,测试通过了意味着函数的行为是对的,而 测试未通过意味着你编写的新代码有错。因此,测试未通过时,不要修改测试,而应修复导致测 试不能通过的代码:检查刚对函数所做的修改,找出导致函数行为不符合预期的修改。 在这个示例中,get_formatted_name()以前只需要两个实参——名和姓,但现在它要求提供 名、中间名和姓。新增的中间名参数是必不可少的,这导致get_formatted_name()的行为不符合 预期。就这里而言,最佳的选择是让中间名变为可选的。这样做后,使用类似于Janis Joplin的姓 名进行测试时,测试就会通过了,同时这个函数还能接受中间名。下面来修改 get_formatted_name(),将中间名设置为可选的,然后再次运行这个测试用例。如果通过了,我 们接着确认这个函数能够妥善地处理中间名。 要将中间名设置为可选的,可在函数定义中将形参middle移到形参列表末尾,并将其默认值 指定为一个空字符串。我们还要添加一个if测试,以便根据是否提供了中间名相应地创建姓名:
name_function.py
def get_formatted_name(first, last, middle=''):"""生成整洁的姓名"""if middle:full_name = first + ' ' + middle + ' ' + lastelse:full_name = first + ' ' + lastreturn full_name.title()
在get_formatted_name()的这个新版本中,中间名是可选的。如果向这个函数传递了中间名 (if middle:),姓名将包含名、中间名和姓,否则姓名将只包含名和姓。现在,对于两种不同的 姓名,这个函数都应该能够正确地处理。为确定这个函数依然能够正确地处理像Janis Joplin这样 的姓名,我们再次运行test_name_function.py:
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
现在,测试用例通过了。太好了,这意味着这个函数又能正确地处理像Janis Joplin这样的姓 名了,而且我们无需手工测试这个函数。这个函数很容易就修复了,因为未通过的测试让我们得 知新代码破坏了函数原来的行为。
关于“Python”的核心知识点整理大全25-CSDN博客
关于“Python”的核心知识点整理大全12-CSDN博客
往期快速传送门👆(在文章最后):
感谢大家的支持!欢迎订阅收藏!专栏将持续更新!
相关文章:

关于“Python”的核心知识点整理大全27
目录 10.5 小结 第11 章 测试代码 11.1 测试函数 name_function.py 函数get_formatted_name()将名和姓合并成姓名,在名和姓之间加上一个空格,并将它们的 首字母都大写,再返回结果。为核实get_formatted_name()像期望的那样工…...

实验三 MapReduce编程
实验目的: 1.掌握MapReduce的基本编程流程; 2.掌握MapReduce序列化的使用; 实验内容: 一、在本地创建名为MapReduceTest的Maven工程,在pom.xml中引入相关依赖包,配置log4j.properties文件,搭…...

element组件库的日期选择器如何限制?
本次项目中涉及到根据日期查找出来的数据进行调整,所以修改的数据必须是查找范围内的数据.需要对调整数据的日期进行限制,效果如下: 首先我们使用了element 组件库的日期选择器,其中灌完介绍, picker-options中函数disabledDate可以设置禁用状态,代码如下: <el-date-pickerv…...
QSqlQueryModel
QSqlQueryModel 是 Qt 框架中的一个模型类,用于在 Qt 的视图组件(如 QTableView、QListView)中显示数据库查询结果。 QSqlQueryModel 继承自 QAbstractTableModel,它通过执行 SQL 查询并将结果存储在内部数据结构中,提…...

docker-compose介绍和用法
docker-compose介绍和用法详解 1、docker-compose介绍2、docker-compose build3、docker-compose down4、docker-compose up -d 1、docker-compose介绍 Docker Compose是一个用于快速配置多个Docker容器的工具。它是一个定义和运行多容器的Docker应用工具,通过YAML…...
Mac下ERROR: Cannot connect to the Docker daemon
解决Mac下ERROR: Cannot connect to the Docker daemon at unix:///Users/qq/.orbstack/run/docker.sock. Is the docker daemon running? 在Mac系统的中, 如果实际已经安装docker并且已经启动了. 但执行 docker info 时 报错: ERROR: Cannot connect to the Docker daemon …...

本地项目添加到gitlab命令操作
gitlab上面创建一个跟项目名同名的文件夹 创建文件夹,填写信息 添加readme文档,先保存下创建的文件夹 回到项目,复制项目的git 地址 然后进入到本地项目的文件夹,如d:/workspace/spring-demo,右键打开git bash弹框 命令…...

t-io 程序执行后,jvm不退出的原因
基于t-io 1.7.3 版本分析源码 1、设定当前时间,每10毫秒执行一次 (非守护线程) 2、对应线程池的核心线程在AioServer启动时全部激活,并且添加空任务到阻塞队列,让核心线程(非守护线程)一直存活...

Vue3使用Three.js导入gltf模型并解决模型为黑色的问题
背景 如今各类数字孪生场景对三维可视化的需求持续旺盛,因为它们可以用来创建数字化的双胞胎,即现实世界的物体或系统的数字化副本。这种技术在工业、建筑、医疗保健和物联网等领域有着广泛的应用,可以帮助人们更好地理解和管理现实世界的事…...

说一下 jvm 有哪些垃圾回收算法?
说一下 jvm 有哪些垃圾回收算法? 一.对象是否已死算法 1.引用计数器算法 2.可达性分析算法 二.GC算法 1.标记清除算法 如果对象被标记后进行清除,会带来一个新的问题–内存碎片化。如果下次有比较大的对象实例需要在堆上分配较大的内存空间时࿰…...

【23真题】一共10道题,押题卷5道!
哈喽大家好,现在这个时间节点,有很多同学开始刷真题了!所以23真题系列正式启动!小马哥将全面发布23真题及详细解析! 小马哥Tips: 今天分享的是23年天津师范大学804的信号与系统试题及解析。这所院校一共出…...

JS的浅拷贝和深拷贝
首先理解什么是浅拷贝和深拷贝: 浅拷贝: 浅拷贝只会复制对象的第一层属性,而不会递归地复制嵌套的对象。浅拷贝仅复制对象的引用,新对象和原始对象仍然共享相同的引用,因此对新对象的修改可能会影响到原始对象。浅拷…...

天软特色因子看板 (2023.12 第12期)
该因子看板跟踪天软特色因子A06008(聪明钱因子(beta),该因子为以分钟行情价量信息为基础,识别聪明钱交易,用以刻画机构交易行为 值越大,越反映其悲观情绪,反之,反映其乐观情绪。 今日为该因子跟踪第12期&am…...

【Logback技术专题】「入门到精通系列教程」深入探索Logback日志框架的原理分析和开发实战技术指南(上篇)
深入探索Logback日志框架的原理分析和开发实战指南系列 Logback日志框架Logback基本模块logback-corelogback-classiclogback-accessLogback的核心类LoggerAppenderLayoutLayout和Appender filterlogback模块和核心所属关系 Logbackj日志级别日志输出级别日志级别介绍 Logback的…...
vue3+element Plus 清空el-tree复选框选中项
前提问题:el-tree加了show-checkbox复选框属性后,在选择完复选框后切换,不会自动清空选中内容,要求在切换时清空复选框选中内容,解决过程:设置el-tree的ref值,使用setCheckedKeys方法可清空复选…...

【VScode】设置语言为中文
1、下载安装好vscode 2、此时可看到页面为英文,为方便使用可切换为中文 3、键盘按下 ctrlshiftP 4、在输入框内输入configure display language 5、选择中文,restart即可(首次会有install安装过程,等待安装成功后重启即可&am…...

C++ Qt开发:TableWidget表格组件
Qt 是一个跨平台C图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍TableWidget表格组件的常用方法及灵活运用。 …...

layui框架实战案例(25):table组件筛选列记忆功能
即点击当前表格右上角筛选图标后,对表头进行显示隐藏勾选,再刷新页面依然保留当前筛选状态。 要实现layui表格组件的筛选列记忆功能,可以采取以下步骤: 存储筛选数据:当用户进行筛选操作时,将筛选的数据…...

20、WEB攻防——PHP特性缺陷对比函数CTF考点CMS审计实例
文章目录 一、PHP常用过滤函数:1.1 与1.2 md51.3 intval1.4 strpos1.5 in_array1.6 preg_match1.7 str_replace CTFshow演示三、参考资料 一、PHP常用过滤函数: 1.1 与 :弱类型对比(不考虑数据类型),甚至…...

互换数组的两个轴 numpy.swapaxes()
【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 互换数组的两个轴 numpy.swapaxes() 选择题 请问下列程序运行的的结果是: import numpy as np arr1 np.array([[11,12],[21,22]]).reshape((2,2)) print("【显示】arr1:\n…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...

uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...

LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...