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. 自定义类,编写测试用例。

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

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

相关文章

LSTM架构的演进:LSTM、xLSTM、LSTM+Transformer

文章目录 1. LSTM2. xLSTM2.1 理论介绍2.2 代码实现 3. LSTMTransformer 1. LSTM 传统的 LSTM (长短期记忆网络) 的计算公式涉及几个关键部分&#xff1a;输入门、遗忘门、输出门和单元状态。 2. xLSTM xLSTM之所以称之为xLSTM就是因为它将LSTM扩展为多个LSTM的变体&#xff…

【LLVM】‘ffast-math’ and ‘ffp-contract’

最近看到一个issue&#xff0c;修改的核心代码部分并不多&#xff0c;可以参考此处的介绍以及此处的issue。 看起来关键就是判断-ffp-contract会将contract的值设为最后一个此选项的值&#xff0c;否则的话&#xff0c;如果只指定了-ffast-math但是没有通过-ffp-contract设置值…

fffdddd

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all;entity GJL isport(clk, reset: in std_logic;btn_green, btn_red: in std_logic; -- 新增控制按键r1, r2, y1, y2, g1, g2: out std_logic;ledag: out std_logic_…

网络编程--网络理论基础(二)

这里写目录标题 网络通信流程mac地址、ip地址arp协议交换机路由器简介子网划分网关 路由总结 为什么ip相同的主机在与同一个互联网服务通信时不冲突公网ip对于同一个路由器下的不同设备&#xff0c;虽然ip不冲突&#xff0c;但是因为都是由路由器的公网ip转发通信&#xff0c;接…

在Java中使用Apache Kafka进行消息队列处理

在Java中使用Apache Kafka进行消息队列处理 消息队列(Message Queue)是分布式系统中用于异步通信的关键组件,广泛应用于解耦生产者和消费者、平滑流量突增、提高系统弹性等场景。Apache Kafka作为一个高吞吐量、分布式的消息队列系统,已经成为许多企业的首选。本文将介绍如…

Linux 进程管理指令

Linux 进程管理是系统管理的重要部分&#xff0c;通过各种工具和命令&#xff0c;你可以查看、控制、调试和管理进程。以下是一些常用的 Linux 进程管理命令和工具。 查看进程 1. ps ps 命令用于列出当前系统的进程。 查看当前用户的所有进程&#xff1a; ps -u $USER查看…

Python statistics 模块

Python 的 statistics 模块提供了一组用于执行各种统计计算的函数&#xff0c;包括平均值、中位数、标准差、方差以及其他统计量。让我来简单介绍一下。 首先&#xff0c;你可以使用以下方式导入 statistics 模块&#xff1a; python import statistics 接下来&#xff0c;…

主流中间件--Redis

NOSQL 什么是NOSQL NoSQL(NoSQL Not Only SQL )&#xff0c;意即“不仅仅是SQL”&#xff0c;它泛指非关系型的数据库。 关系型数据库&#xff1a;以关系(由行和列组成的二维表)模型建模的数据库。简单理解&#xff1a;有表的就是关系型数据库。 NOSQL分类 Redis 什么是Redi…

内容安全复习 7 - 对抗攻击与防御

文章目录 概述攻击对抗性攻击的目的攻击的损失函数如何攻击FGSM黑盒与白盒真实世界的攻击 防御被动防御主动防御 概述 动机 &#xff08;1&#xff09;不仅要在实验室中部署机器学习分类器&#xff0c;也要在现实世界中部署&#xff1b;实际应用 &#xff08;2&#xff09;分类…

shell jq教程

1. jq 简介 jq 是一款命令行下处理JSON数据的工具。其可以接受标准输入&#xff0c;命令管道或者文件中的JSON数据&#xff0c;经过一系列的过滤器(filters)和表达式的转后形成我们需要的数据结构并将结果输出到标准输出中。jq的这种特性使我们可以很容易地在Shell脚本中调用它…

LeetCode 23. 合并 K 个升序链表

更多题解尽在 https://sugar.matrixlab.dev/algorithm 每日更新。 组队打卡&#xff0c;更多解法等你一起来参与哦&#xff01; LeetCode 23. 合并 K 个升序链表&#xff0c;难度困难。 优先队列&#xff08;小顶堆&#xff09; 解题思路&#xff1a;拿到题首先想到以下几个方…

【数据结构】线性表之《栈》超详细实现

栈 一.栈的概念及结构二.顺序栈与链栈1.顺序栈2.链栈1.单链表栈2.双链表栈 三.顺序栈的实现1.栈的初始化2.检查栈的容量3.入栈4.出栈5.获取栈顶元素6.栈的大小7.栈的判空8.栈的清空9.栈的销毁 四.模块化源代码1.Stack.h2.Stack.c3.test.c 一.栈的概念及结构 栈&#xff1a;一种…

程序猿成长之路之数据挖掘篇——决策树分类算法(1)——信息熵和信息增益

决策树不仅在人工智能领域发挥着他的作用&#xff0c;而且在数据挖掘中也在分类领域中独占鳌头。了解决策树的思想是学习数据挖掘中的分类算法的关键&#xff0c;也是学习分类算法的基础。 什么是决策树 用术语来说&#xff0c;决策树&#xff08;Decision Tree&#xff09;是…

Go自定义数据的序列化流程

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

数据库设计概述-数据库设计内容、数据库设计方法(基于E-R模型的规范设计方法)

一、引言 如何利用关系数据库理论设计一个满足应用系统需求的数据库 二、数据库设计内容 1、数据库设计是基于应用系统需求分析中对数据的需求&#xff0c;解决数据的抽象、数据的表达和数据的存储结构等问题 2、其目标是设计出一个满足应用要求、简洁、高效、规范合理的数…

Map集合之HashMap细说

最近在看面试题&#xff0c;看到了hashmap相关的知识&#xff0c;面试中问的也挺多的&#xff0c;然后我这里记录下来&#xff0c;供大家学习。 Hashmap为什么线程不安全 jdk 1.7中&#xff0c;在扩容的时候因为使用头插法导致链表需要倒转&#xff0c;从而可能出现循环链表问…

航行在水域:使用数据湖构建生产级 RAG 应用程序

在 2024 年年中&#xff0c;创建一个令人印象深刻和兴奋的 AI 演示可能很容易。需要一个强大的开发人员&#xff0c;一些聪明的提示实验&#xff0c;以及一些对强大基础模型的API调用&#xff0c;你通常可以在一个下午建立一个定制的AI机器人。添加一个像 langchain 或 llamain…

c++ 内存分析模型、引用

一、内存模型分区 内存四区的意义&#xff1a; 不同区域存放的数据&#xff0c;赋予不同的生命周期&#xff0c;给我们更大的灵活编程 &#xff08;一&#xff09;程序运行前 在程序编译后&#xff0c;生成了exe可执行程序&#xff0c;未执行程序前分为两个区域 代码区&…

2024hw蓝队面试题--4

SQL注入特征&#xff0c;误报原因以及怎么处理告警&#xff1f; 1.非法字符检测&#xff1a;这种类型的攻击通常会使用特殊字符&#xff0c;如单引号()、双引号(")、分号(;)、注释符号(--或/、/)等。检测输入中是否包含这类特殊字符是识别SQL注入攻击的一种方法。 2.堆栈…

PostgreSQL源码分析——审计插件pgaudit

PostgreSQL审计插件pgaudit 在PostgreSQL中&#xff0c;提供了开源的审计插件pgaudit&#xff0c;但是其功能并不完善&#xff0c;只提供了基本的审计功能&#xff0c;对此&#xff0c;很多基于PG开发的商业数据库大多提供了丰富的审计功能。比如人大金仓&#xff0c;openGaus…