关于“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 + ' ' + last
 return 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':
 break
 last = input("Please give me a last name: ")
 if last == 'q':
 break
 formatted_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: joplin
 Neatly formatted name: Janis Joplin.
Please give me a first name: bob
Please give me a last name: dylan
 Neatly 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 + ' ' + last
 return 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_name
 formatted_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 + ' ' + last
 else:
 full_name = first + ' ' + last
 return 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博客

往期快速传送门👆(在文章最后):

感谢大家的支持!欢迎订阅收藏!专栏将持续更新!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【超图】SuperMap iClient3D for WebGL/WebGPU ——地形影像

作者:taco 号外!号外!开新坑了!开新坑了!对于一个代码小白来讲,设置可能是刚接触开发的人(还没接触准备接触)的人来说。对于读代码或是在对产品的使用上会存在许许多多的疑惑。接下来…

uniapp笔记

/pages/component/swiper/swiper /pages/component/button/button navigator image 设置界面标题 页面跳转 设置TabBar 发起一个请求 网络请求

计算机组成原理——中央处理器cpu1-20

1、中央处理器(CPU)是指什么。C A、 运算器 B、 控制器 C、 运算器和控制器 D、 运算器、控制器和主存储器 2、在CPU中跟踪指令后继地址的寄存器是什么。B A、 主存地址寄存器 B、 程序计数器 C、 指令寄存器 D、 状态条件寄存器 3、操作控制器的…

VR党建:VR全景技术如何助力党建知识传播

导语: 随着科技的不断发展,虚拟现实技术逐渐深入人们生活的方方面面。VR全景技术作为一种全新的沉浸式体验方式,被广泛应用于娱乐、教育、医疗等领域。而在党建学习中,VR全景技术也展现出了巨大的潜力,成为了一种创新…

项目中webpack优化配置(持续更新)

项目中webpack优化配置 1. 开发效率, 体验 DLL(开发过程中减少构建时间和增加应用程序的性能) 使用 DllPlugin 进行分包,使用 DllReferencePlugin(索引链接) 对 manifest.json 引用,让一些基本不会改动的代码先打包…

java-sec-code中的文件上传

java-sec-code中的文件上传 这里仅讨论文件上传,不讨论后续利用(中间件解析漏洞等不做讨论) 任意文件伤害上传 any-->uploada.html-->upload访问any路由时,会出现upload.html的上传文件界面,指向upload路由 GetMapping("/any&qu…

java SSM教师业绩管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM教师业绩管理系统是一套完善的web设计系统(系统采用SSM框架进行设计开发,springspringMVCmybatis),对理解JSP java编程开发语言有帮助,系统具有完整的源代 码和数据库,系统主要采…

谷歌发布Gemini 1.0,开启生成式AI模型新时代!

🎥 屿小夏 : 个人主页 🔥个人专栏 : IT杂谈 🌄 莫道桑榆晚,为霞尚满天! 文章目录 📑前言一. Gemini的发布前期1.1 Gemini的准备1.2 DeepMnid 二. Gemini的三大杀手锏2.1 多模态能力2…

Linux 音视频SDK开发实践

一、兼容性适配处理 为什么需要兼容处理? 1、c兼容处理 主要有ABI兼容性问题,不同ubuntu系统依赖的ABI版本如下: ubuntu 18.04ubuntu 16.04ubuntu 14.04g7.55.44.8stdc版本libstdc.so.6.0.25libstdc.so.6.0.21libstdc.so.6.0.19GLIBCXXG…

详解YOLOv5网络结构/数据集获取/环境搭建/训练/推理/验证/导出/部署

一、本文介绍 本文给大家带来的教程是利用YOLOv5训练自己的数据集,以及有关YOLOv5的网络结构讲解/数据集获取/环境搭建/训练/推理/验证/导出/部署相关的教程,同时通过示例的方式让大家来了解具体的操作流程,过程中还分享给大家一些好用的资源…

电脑备忘录小工具怎么添加?怎么在电脑桌面添加备忘录?

作为一名天天用电脑办公的上班族,如果你需要对某个项目或问题进入深入思考,想要快速记录想法和思路,这时候会选择什么样的记事方式呢?如果你需要记录常用的工作文字内容、工作注意事项、项目流程、待办的工作安排等,用…

vue 将后端返回的二进制流进行处理并实现下载

什么是二进制流文件? 二进制文件是一种计算机文件格式,它的数据以二进制形式存储,与文本文件不同。二进制文件可以包含任意类型的数据,例如图像、音频、视频、可执行文件、压缩文件等,而文本文件则仅仅包含 ASCII 码或…

PCL 点云匹配 之NICP(Normal ICP)

一、概述 上面一篇中我们已经得出了一个结论,就是ICP虽然简单,但是也有明显的缺点 1、计算速度慢,收敛慢,迭代次数多 2、对内存的开销比较大 3、很容易陷入局部最优的困局 因此我们在经典ICP的基础上添加一两个约束: 第…

鸿蒙开发之简单登录页面

Entry Component struct Index {State loading:booleanfalse;build() {Row() {Column({ space: 5 }) {Image($r("app.media.app_icon")).width(100).height(100).borderRadius(10).margin({top: 60})Text("登录界面").fontSize(40).fontWeight(FontWeight.…

Apollo Planning——PathLaneBorrowDecider

引用 组件数据缓存 DependencyInjector DependencyInjector:依赖注入器,这是一个过于专业的名词,来自软件设计模式的依赖倒置原则的一种具体实现方式,起到模块解耦作用。“依赖倒置原则(Dependence Inversion Principle)是程序要…

全国国控监测点点位数据,shp/excel格式,已可视化

基本信息. 数据名称: 全国国控监测点点位数据 数据格式: shpexcel 时间版本:2023年 数据几何类型: 点 数据精度:全国 数据坐标系: WGS84 数据来源:网络公开数据 数据字段: 序号字段名称字段说明1province省名称2city城市…

设计模式 原型模式 与 Spring 原型模式源码解析(包含Bean的创建过程)

原型模式 原型模式(Prototype模式)是指:用原型实例指定创建对象的种类,并且通过拷贝这些原型,创建新的对象。 原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象,无需知道如何创建的细节。 工作原…

SQLturning:定位连续值范围起点和终点

在上一篇blog说到,如何去优化查询连续值范围,没看过的朋友,上篇blog链接[在此]。(https://blog.csdn.net/weixin_42575078/article/details/135067645?spm1001.2014.3001.5501) 那么今天来说说怎么将连续的数据合并,然后返回合并…

Android的组件、布局学习

介绍 公司组织架构调整,项目组需要承接其他项目组的android项目,负责维护和开发新需求,故学习下基础语法和项目开发。 组件学习 Toolbarheader布局部分 就是app最顶部的部分 他的显示与否,是与F:\androidProject\android_lear…

HTML有哪些列表以及具体的使用!!!

文章目录 一、HTML列表二、列表的应用1、无序列表2、有序列表3、自定义列表 三、总结 一、HTML列表 html的列表有三种&#xff0c;一种是无序列表&#xff0c;一种是有序列表&#xff0c;还有一种为自定义列表。 二、列表的应用 1、无序列表 <ul> <li>无序列表…