Python学习笔记17:进阶篇(六)代码测试

2024-06-23 11:28

本文主要是介绍Python学习笔记17:进阶篇(六)代码测试,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

代码测试

代码测试是软件开发过程中的关键环节,旨在确保代码质量、功能正确性以及性能符合预期。

在开发过程中,进行代码测试有很多好处:

  1. 提高软件质量:通过发现并修复错误,测试有助于提升软件的功能性、可靠性和稳定性,减少用户遇到的问题。
  2. 降低维护成本:及早发现错误可以减少后期修复的复杂度和成本,因为错误在系统更复杂时更难追踪和修正。
  3. 加速开发流程:自动化测试能够快速反馈代码变更的效果,使得开发者能迅速定位问题,加快迭代速度。
  4. 增强信心:全面的测试套件为开发团队和利益相关者提供了部署代码的信心,知道改动不太可能引入新的错误。
  5. 促进可维护性和可扩展性:编写可测试的代码往往意味着更好的模块化和解耦,这有利于未来的维护和功能扩展。
  6. 文档作用:测试用例本身也起到了文档的作用,展示了代码应该如何被使用,以及预期的行为是什么。
  7. 便于重构:有了坚实的测试基础,开发者可以更加大胆地进行代码重构,优化结构而不必过分担心引入新bug。
  8. 提升团队协作:共同的测试标准和实践促进了团队成员之间的沟通和理解,确保了项目的一致性和质量标准。

作为python学习者,我们更加需要学习代码的测试知识,因为python是自动化测试的首选语言。

测试工具

unittest

unittest是Python标准库中的一个模块,提供了编写和运行测试的强大工具。

  1. 测试用例:每个测试用例通常对应一个函数,使用test_前缀命名。
  2. 断言方法:如assertEqual()、assertTrue()等,用于比较实际结果与预期结果。
  3. 测试套件:使用unittest.TestSuite来组织多个测试用例。
  4. 测试运行器:使用unittest.TextTestRunner来执行测试。

if name == ‘main’:

插个小知识,以免后面看不懂。

在Python程序中,if name == ‘main’: 是一个常见的条件语句,其作用在于判断当前文件是否作为主程序直接被执行。如果文件是被直接执行,那么这个条件下的代码块将会被执行;反之,如果文件是被导入到其他模块中,则该代码块不会执行。这样的设计允许模块既可以作为独立的程序运行,又可以在其他程序中被引用而不会执行主程序的代码。

为什么需要这个判断?

  1. 避免重复执行:当一个模块被其他模块导入时,如果模块中有全局执行的代码(比如打印语句、初始化操作等),如果不加此判断,这些代码就会被执行。这对于只想使用该模块中定义的函数或类的其他模块来说,可能会产生意料之外的结果或副作用。

  2. 便于组织代码:将程序的入口点统一放在这一块,使得代码结构更加清晰。特别是对于包含多个函数和类的大型模块,这种方式有助于区分哪些代码是用来测试或演示模块功能的,哪些是模块的核心功能定义。

def hello(name):print(f"Hello, {name}!")if __name__ == '__main__':hello("World")

在这个例子中,hello函数定义了一个简单的打招呼功能。当直接运行这个脚本时,因为__name__变量的值为’main’,所以会执行下面的代码块,打印出"Hello, World!"。但如果这个模块被其他脚本导入,hello函数可以被正常使用,但打招呼的那行代码不会执行,除非导入模块的脚本也显式调用了hello函数。

测试示例

测试函数

import unittest
from operator import addclass TestAddFunction(unittest.TestCase):def test_add(self):self.assertEqual(add(1, 2), 3)self.assertEqual(add(-1, 1), 0)self.assertEqual(add(0, 0), 0)if __name__ == '__main__':unittest.main()

这段代码中,我们使用了断言assertEqual来测试我们add函数的正确性。
在这里插入图片描述
以上是代码测试通过的示例,假如有错误的结果又会是怎么样的呢?我们还是以add函数示例。

import unittest
from operator import addclass TestAddFunction(unittest.TestCase):def test_add(self):self.assertEqual(add(1, 2), 3)self.assertEqual(add(-1, 1), 2)self.assertEqual(add(0, 0), 0)if __name__ == '__main__':unittest.main()

我们修改第二个断言中的函数预期值,并点击执行。
在这里插入图片描述
最终运行框中提示了第二个断言的错误,预期是0但是我们给的值是2,这是一个不能通过的测试。

能够正常通过的测试有了,不能通过的测试也有了。遇到不能通过的测试怎么呢?

首先,你应该检查你的输入参数,如果你能保证你的输入参数没有问题那么说明你的函数还有问题存在,需要修复。这个时候需要我们修改的是函数本身的逻辑,而不是测试的代码。通过debug的方式找到影响正确输出的代码进行修改即可。

测试类

先准备需要测试目标类。

class BankAccount:def __init__(self):self.balance = 0def deposit(self, amount):"""存款"""if amount > 0:self.balance += amountelse:raise ValueError("存款金额必须大于0")def withdraw(self, amount):"""取款"""if 0 < amount <= self.balance:self.balance -= amountelse:raise ValueError("取款金额必须大于0且不超过账户余额")def get_balance(self):"""查询余额"""return self.balance

编写一个测试实施类,对测试目标类进行测试。

import unittest
from bank_account import BankAccountclass TestBankAccount(unittest.TestCase):def setUp(self):"""每个测试方法执行前的准备工作"""self.account = BankAccount()def test_initial_balance(self):"""测试初始余额是否为0"""self.assertEqual(self.account.get_balance(), 0)def test_deposit(self):"""测试存款功能"""self.account.deposit(100)self.assertEqual(self.account.get_balance(), 100)def test_withdraw(self):"""测试取款功能"""self.account.deposit(800)self.account.withdraw(600)self.assertEqual(self.account.get_balance(), 200)def test_negative_deposit(self):"""测试尝试存入负数时是否抛出异常"""with self.assertRaises(ValueError):self.account.deposit(-50)def test_overdraft_withdraw(self):"""测试尝试超限取款时是否抛出异常"""self.account.deposit(100)with self.assertRaises(ValueError):self.account.withdraw(900)if __name__ == '__main__':unittest.main()

在这里插入图片描述
这就是简单对类进行测试。

断言

断言方法是测试用例的核心,用于比较实际结果与预期结果,从而判断测试是否通过。以下是一些常用的断言方法及其用途:

assertEqual(a, b):检查a和b是否相等。
assertTrue(x):检查x是否为True。
assertFalse(x):检查x是否为False。
assertIn(item, list):检查item是否在list中。
assertNotIn(item, list):检查item是否不在list中。
assertIsNone(x):检查x是否为None。
assertIsNotNone(x):检查x是否不为None。
assertAlmostEqual(a,b):检查浮点数a和b是否足够接近(默认容差为7个十进制位)。
assertRaises(exc, callable, *args,**kwargs):检查在调用callable(*args, **kwargs)时是否抛出exc异常。

测试套件和测试运行器

测试套件就是将多个测试用例组合在一起,一次性执行。在需要组织和管理大量测试时会很有帮助。
测试运行器则是负责执行测试套件并收集测试结果。最常用的运行器是unittest.TextTestRunner,它会打印测试结果到控制台。

import unittest# 假设有两个测试类
class TestAddition(unittest.TestCase):def test_add(self):self.assertEqual(1 + 1, 2)class TestSubtraction(unittest.TestCase):def test_subtract(self):self.assertEqual(3 - 1, 2)# 创建测试套件
suite = unittest.TestSuite()# 将测试用例添加到套件中
suite.addTest(TestAddition('test_add'))
suite.addTest(TestSubtraction('test_subtract'))# 运行测试套件
runner = unittest.TextTestRunner(verbosity=2)
runner.run(suite)

如代码示例,将多个测试用例组合到一起,一次执行,全部测试。

在这里插入图片描述

结尾

测试内容基本就这里结束了,没办法写的很深入,一个是本人水平问题,一个代码这东西,总归要是要结合到项目里面自己实战,发现问题到解决问题,这样才能有收获,才能有进步,才能有收获。当然初学时的练习也不要忘了!

作业

除了已经示例过的断言,增加两三个其他的断言进行使用,测试套件和测试运行器也别忘了用上。

  1. 自定义函数,并编写测试用例。
  2. 自定义类,编写测试用例。

这篇关于Python学习笔记17:进阶篇(六)代码测试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1087024

相关文章

一文带你搞懂Python中__init__.py到底是什么

《一文带你搞懂Python中__init__.py到底是什么》朋友们,今天我们来聊聊Python里一个低调却至关重要的文件——__init__.py,有些人可能听说过它是“包的标志”,也有人觉得它“没... 目录先搞懂 python 模块(module)Python 包(package)是啥?那么 __in

使用Python实现图像LBP特征提取的操作方法

《使用Python实现图像LBP特征提取的操作方法》LBP特征叫做局部二值模式,常用于纹理特征提取,并在纹理分类中具有较强的区分能力,本文给大家介绍了如何使用Python实现图像LBP特征提取的操作方... 目录一、LBP特征介绍二、LBP特征描述三、一些改进版本的LBP1.圆形LBP算子2.旋转不变的LB

Python中__init__方法使用的深度解析

《Python中__init__方法使用的深度解析》在Python的面向对象编程(OOP)体系中,__init__方法如同建造房屋时的奠基仪式——它定义了对象诞生时的初始状态,下面我们就来深入了解下_... 目录一、__init__的基因图谱二、初始化过程的魔法时刻继承链中的初始化顺序self参数的奥秘默认

Python实现特殊字符判断并去掉非字母和数字的特殊字符

《Python实现特殊字符判断并去掉非字母和数字的特殊字符》在Python中,可以通过多种方法来判断字符串中是否包含非字母、数字的特殊字符,并将这些特殊字符去掉,本文为大家整理了一些常用的,希望对大家... 目录1. 使用正则表达式判断字符串中是否包含特殊字符去掉字符串中的特殊字符2. 使用 str.isa

python中各种常见文件的读写操作与类型转换详细指南

《python中各种常见文件的读写操作与类型转换详细指南》这篇文章主要为大家详细介绍了python中各种常见文件(txt,xls,csv,sql,二进制文件)的读写操作与类型转换,感兴趣的小伙伴可以跟... 目录1.文件txt读写标准用法1.1写入文件1.2读取文件2. 二进制文件读取3. 大文件读取3.1

使用Python实现一个优雅的异步定时器

《使用Python实现一个优雅的异步定时器》在Python中实现定时器功能是一个常见需求,尤其是在需要周期性执行任务的场景下,本文给大家介绍了基于asyncio和threading模块,可扩展的异步定... 目录需求背景代码1. 单例事件循环的实现2. 事件循环的运行与关闭3. 定时器核心逻辑4. 启动与停

基于Python实现读取嵌套压缩包下文件的方法

《基于Python实现读取嵌套压缩包下文件的方法》工作中遇到的问题,需要用Python实现嵌套压缩包下文件读取,本文给大家介绍了详细的解决方法,并有相关的代码示例供大家参考,需要的朋友可以参考下... 目录思路完整代码代码优化思路打开外层zip压缩包并遍历文件:使用with zipfile.ZipFil

Python处理函数调用超时的四种方法

《Python处理函数调用超时的四种方法》在实际开发过程中,我们可能会遇到一些场景,需要对函数的执行时间进行限制,例如,当一个函数执行时间过长时,可能会导致程序卡顿、资源占用过高,因此,在某些情况下,... 目录前言func-timeout1. 安装 func-timeout2. 基本用法自定义进程subp

Python实现word文档内容智能提取以及合成

《Python实现word文档内容智能提取以及合成》这篇文章主要为大家详细介绍了如何使用Python实现从10个左右的docx文档中抽取内容,再调整语言风格后生成新的文档,感兴趣的小伙伴可以了解一下... 目录核心思路技术路径实现步骤阶段一:准备工作阶段二:内容提取 (python 脚本)阶段三:语言风格调

Python结合PyWebView库打造跨平台桌面应用

《Python结合PyWebView库打造跨平台桌面应用》随着Web技术的发展,将HTML/CSS/JavaScript与Python结合构建桌面应用成为可能,本文将系统讲解如何使用PyWebView... 目录一、技术原理与优势分析1.1 架构原理1.2 核心优势二、开发环境搭建2.1 安装依赖2.2 验