编程与数学 02-017 Python 面向对象编程 23课题、测试面向对象的程序

  • 一、单元测试(Unit Testing)
        • 使用 `unittest` 模块
        • 使用 `pytest`
  • 二、集成测试(Integration Testing)
  • 三、模拟对象(Mocking)
  • 四、测试驱动开发(TDD)
  • 五、测试覆盖率
  • 六、持续集成(CI)
  • 全文总结

摘要:本文介绍了 Python 面向对象编程中的测试方法,包括单元测试、集成测试、模拟对象、测试驱动开发、测试覆盖率和持续集成。通过详细示例,展示了如何使用 unittestpytest 进行单元测试,如何进行集成测试和模拟外部依赖,以及如何通过 TDD 方法开发代码。同时,介绍了如何使用 coverage 工具测量测试覆盖率,并通过 CI 工具实现自动化测试流程。这些方法有助于提高代码质量,确保软件的稳定性和可靠性。

关键词:Python,面向对象编程,单元测试,集成测试,模拟对象,测试驱动开发,测试覆盖率,持续集成

人工智能助手:Kimi


一、单元测试(Unit Testing)

单元测试是对程序中的最小可测试部分(通常是函数或方法)进行测试。Python 提供了内置的 unittest 模块,用于编写和运行单元测试。

使用 unittest 模块

unittest 是 Python 的标准测试框架,提供了丰富的测试功能。

示例代码
假设我们有一个简单的类 Calculator,我们想对其进行单元测试。

# calculator.py
class Calculator:def add(self, a, b):return a + bdef subtract(self, a, b):return a - bdef multiply(self, a, b):return a * bdef divide(self, a, b):if b == 0:raise ValueError("Cannot divide by zero")return a / b

接下来,我们使用 unittest 编写测试代码:

# test_calculator.py
import unittest
from calculator import Calculatorclass TestCalculator(unittest.TestCase):def setUp(self):self.calc = Calculator()def test_add(self):self.assertEqual(self.calc.add(1, 2), 3)def test_subtract(self):self.assertEqual(self.calc.subtract(5, 3), 2)def test_multiply(self):self.assertEqual(self.calc.multiply(4, 3), 12)def test_divide(self):self.assertEqual(self.calc.divide(10, 2), 5)def test_divide_by_zero(self):with self.assertRaises(ValueError):self.calc.divide(10, 0)if __name__ == "__main__":unittest.main()

运行测试
在命令行中运行以下命令:

python -m unittest test_calculator.py

如果所有测试通过,会输出类似以下内容:

....
----------------------------------------------------------------------
Ran 4 tests in 0.001sOK
使用 pytest

pytest 是一个第三方测试框架,提供了更简洁的语法和更强大的功能,如自动发现测试用例、参数化测试等。

安装 pytest

pip install pytest

示例代码
使用 pytest 编写测试代码:

# test_calculator.py
from calculator import Calculatordef test_add():calc = Calculator()assert calc.add(1, 2) == 3def test_subtract():calc = Calculator()assert calc.subtract(5, 3) == 2def test_multiply():calc = Calculator()assert calc.multiply(4, 3) == 12def test_divide():calc = Calculator()assert calc.divide(10, 2) == 5def test_divide_by_zero():calc = Calculator()with pytest.raises(ValueError):calc.divide(10, 0)

运行测试
在命令行中运行以下命令:

pytest test_calculator.py

如果所有测试通过,会输出类似以下内容:

============================= test session starts ==============================
platform linux -- Python 3.x.x, pytest-7.x.x, pluggy-1.x.x
rootdir: /path/to/your/project
collected 5 itemstest_calculator.py .....                                                   [100%]============================== 5 passed in 0.01s ===============================

二、集成测试(Integration Testing)

集成测试是测试多个模块或组件之间的交互。它确保各个模块在集成后能够正常工作。

示例
假设我们有两个类 DatabaseUserManager,它们之间有交互,我们想测试它们的集成。

# database.py
class Database:def __init__(self):self.users = {}def add_user(self, user_id, user_data):self.users[user_id] = user_datadef get_user(self, user_id):return self.users.get(user_id)# user_manager.py
from database import Databaseclass UserManager:def __init__(self, db):self.db = dbdef create_user(self, user_id, user_data):self.db.add_user(user_id, user_data)def get_user(self, user_id):return self.db.get_user(user_id)

集成测试代码

# test_integration.py
import unittest
from user_manager import UserManager
from database import Databaseclass TestIntegration(unittest.TestCase):def setUp(self):self.db = Database()self.user_manager = UserManager(self.db)def test_create_and_get_user(self):user_id = "user123"user_data = {"name": "John Doe", "email": "john@example.com"}self.user_manager.create_user(user_id, user_data)retrieved_user = self.user_manager.get_user(user_id)self.assertEqual(retrieved_user, user_data)if __name__ == "__main__":unittest.main()

三、模拟对象(Mocking)

在测试中,我们经常需要模拟某些对象的行为,尤其是那些依赖外部资源的对象(如数据库、网络服务等)。Python 的 unittest.mock 模块提供了强大的模拟功能。

示例
假设我们有一个类 EmailService,它依赖于一个外部的邮件发送服务。

# email_service.py
import smtplibclass EmailService:def send_email(self, to_address, subject, body):with smtplib.SMTP("smtp.example.com") as server:server.sendmail("from@example.com", to_address, f"Subject: {subject}\n\n{body}")

我们可以在测试中模拟 smtplib.SMTP 的行为:

# test_email_service.py
import unittest
from unittest.mock import patch, MagicMock
from email_service import EmailServiceclass TestEmailService(unittest.TestCase):@patch("smtplib.SMTP")def test_send_email(self, mock_smtp):email_service = EmailService()email_service.send_email("to@example.com", "Test Subject", "Test Body")mock_smtp.assert_called_once_with("smtp.example.com")mock_smtp.return_value.sendmail.assert_called_once_with("from@example.com", "to@example.com", "Subject: Test Subject\n\nTest Body")if __name__ == "__main__":unittest.main()

四、测试驱动开发(TDD)

测试驱动开发(TDD)是一种开发方法,它要求在编写实际代码之前先编写测试代码。TDD 的核心步骤是:

  1. 编写测试:编写一个失败的测试用例。
  2. 编写代码:编写足够的代码以使测试通过。
  3. 重构:优化代码,确保测试仍然通过。

示例
假设我们要开发一个简单的 Stack 类,使用 TDD 的方式开发:

  1. 编写测试
# test_stack.py
import unittest
from stack import Stackclass TestStack(unittest.TestCase):def test_push_and_pop(self):stack = Stack()stack.push(1)stack.push(2)self.assertEqual(stack.pop(), 2)self.assertEqual(stack.pop(), 1)def test_empty(self):stack = Stack()self.assertTrue(stack.is_empty())stack.push(1)self.assertFalse(stack.is_empty())if __name__ == "__main__":unittest.main()
  1. 编写代码
# stack.py
class Stack:def __init__(self):self.items = []def push(self, item):self.items.append(item)def pop(self):if not self.is_empty():return self.items.pop()raise IndexError("pop from empty stack")def is_empty(self):return len(self.items) == 0
  1. 运行测试
    运行测试确保所有测试通过。

五、测试覆盖率

测试覆盖率是指被测试代码中被执行的代码比例。高覆盖率意味着更多的代码被测试覆盖,从而减少潜在的错误。Python 的 coverage 工具可以帮助我们测量测试覆盖率。

安装 coverage

pip install coverage

运行测试并生成覆盖率报告

coverage run -m unittest test_calculator.py
coverage report

这将生成一个覆盖率报告,显示每个文件的测试覆盖率。

六、持续集成(CI)

持续集成是一种软件开发实践,团队成员频繁地将代码集成到共享存储库中。每次集成都会通过自动化构建和测试来验证代码。常见的 CI 工具有 Jenkins、GitHub Actions、GitLab CI 等。

示例
在 GitHub Actions 中设置 CI 流程:

# .github/workflows/ci.yml
name: CIon: [push, pull_request]jobs:build:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v3- name: Set up Pythonuses: actions/setup-python@v4with:python-version: '3.x'- name: Install dependenciesrun: |python -m pip install --upgrade pippip install pytest coverage- name: Run testsrun: |pytest --cov=.- name: Upload coverage to Codecovuses: codecov/codecov-action@v3

全文总结

本文全面介绍了 Python 面向对象编程中的测试方法,旨在帮助开发者提高代码质量和软件稳定性。首先,单元测试通过 unittestpytest 框架对代码中的最小单元(如函数或方法)进行验证,确保其按预期工作。集成测试则关注多个模块或组件之间的交互,通过示例展示了如何测试 DatabaseUserManager 的集成。模拟对象部分通过 unittest.mock 模块展示了如何模拟外部依赖,例如模拟邮件发送服务。测试驱动开发(TDD)部分通过开发一个简单的 Stack 类,展示了编写测试用例、实现代码并通过测试的完整流程。测试覆盖率部分介绍了如何使用 coverage 工具测量代码的测试覆盖率,确保更多代码被测试覆盖。最后,持续集成(CI)部分通过 GitHub Actions 的示例,展示了如何实现自动化构建和测试流程。这些测试方法和工具的结合使用,为 Python 面向对象编程提供了强大的质量保障手段。

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

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

相关文章

[React]Antd Cascader组件地区选择

前言表单中添加一个地区选择功能&#xff0c;要求支持增删改查功能。Cascader 使用Cascader组件动态加载地区选项。使用 loadData 实现动态加载选项&#xff0c;&#xff08;loadData 与 showSearch 无法一起使用&#xff09;。 这里使用了Form.Item组件。 <Form.Itemlabel{…

深度学习-----《PyTorch神经网络高效训练与测试:优化器对比、激活函数优化及实战技巧》

一、训练过程并行批量训练机制一次性输入64个批次数据&#xff0c;创建64个独立神经网络并行训练。所有网络共享参数&#xff08;Ω&#xff09;&#xff0c;更新时计算64个批次的平均损失&#xff0c;统一更新全局参数。梯度更新策略使用torch.no_grad()上下文管理器清理反向传…

Matplotlib 可视化大师系列(五):plt.pie() - 展示组成部分的饼图

目录Matplotlib 可视化大师系列博客总览Matplotlib 可视化大师系列&#xff08;五&#xff09;&#xff1a;plt.pie() - 展示组成部分的饼图一、 饼图是什么&#xff1f;何时使用&#xff08;何时避免&#xff09;&#xff1f;二、 函数原型与核心参数三、 从入门到精通&#x…

C++ Core Guidelines 核心理念

引言 C 是一门功能强大但复杂性极高的编程语言。为了帮助开发者更高效、安全地使用现代 C&#xff0c;C 核心指南&#xff08;CppCoreGuidelines&#xff09;应运而生。这份由 C 之父 Bjarne Stroustrup 等人主导的指南&#xff0c;提供了大量关于 C 编码的规则、最佳实践和设…

vue3 - 组件间的传值

组件间传参 父传子v-on/props 父组件使用v-on:绑定要传的参数:parentData"parentData"&#xff1a; <template><div><Child1 :parentData"parentData"></Child1></div> </template> <script setup lang"ts…

Kafka 在 6 大典型用例的落地实践架构、参数与避坑清单

一、选型速查表场景关键目标推荐清单&#xff08;示例&#xff09;消息&#xff08;Messaging&#xff09;解耦、低延迟、可靠投递acksall、enable.idempotencetrue、retries>0、min.insync.replicas2、合理分区键、DLT网站活动追踪吞吐极高、可回放主题按类型拆分&#xff…

Node.js(1)—— Node.js介绍与入门

前面我们谈到一些前端开发的内容&#xff0c;学习了HTML、css和JavaScript&#xff0c;已经掌握了如何编写一些简单功能的网页。但是只属于前端部分&#xff0c;我们只能在本地打开文件进行浏览&#xff0c;不能让其他人打开我们编写的网站&#xff1b;这时就需要后端部分上场了…

Python办公——爬虫百度翻译网页版(自制翻译小工具——进阶更新版)

目录 专栏导读 前言 项目概述 功能特点 技术栈 核心架构设计 类结构设计 界面布局设计 核心功能实现 1. 智能语言检测 2. 异步翻译处理 3. HTTP请求处理 4. 结果解析与显示 界面设计亮点 1. 响应式布局 2. 用户体验优化 3. 现代化组件 技术难点与解决方案 1. 跨线程UI更新 2. U…

CentOS7 + Docker 部署 Dify 超详细图文教程

如今Agent在互联网上大行其道&#xff0c;网上吵得火热&#xff0c;各个企业也都想搭建自己的Agent。COZE的开源还有最近新出的JoyAgent也都让大家跃跃欲试&#xff0c;今天为大家带来的是Dify的部署方式&#xff0c;相比其他工作流平台&#xff0c;Dify对于整个Agent制作的流程…

vscode(MSVC)进行c++开发的时,在debug时查看一个eigen数组内部的数值

vscode进行c开发的时&#xff0c;在debug时查看一个eigen数组内部的数值问题描述解决方案拓展其他可视化使用visual studio时的可视化使用别的编译器的可视化问题描述 使用vscode进行c开发&#xff0c;编译器是MSVC&#xff0c;在debug的时候想查看一个eigen数组的数值&#x…

【51单片机】【protues仿真】基于51单片机八路抢答器数码管系统

目录 一、主要功能 二、使用步骤 三、硬件资源 四、软件设计 五、实验现象 一、主要功能 1、数码管显示 2、主持人按下开始&#xff0c;8位选手开始抢答 3、第一次使用要设置抢答时间&#xff0c;支持掉电存储 4、选手抢答成功&#xff0c;数码管会显示其号码 5、按下主…

深度学习:CUDA、PyTorch下载安装

目录 一、安装准备 二、安装CUDA 2.1 查看本机支持的 CUDA 版本及相关信息 2.2 卸载CUDA(可选) 2.3 下载cuda安装包 2.4 安装 2.5 配置环境变量 三、安装PyTorch 3.1 版本选择 3.2 下载安装 方法一&#xff1a;直接安装&#xff08;不建议&#xff0c;网差的话会死机…

MyBatis-Plus 快速入门 -常用注解

目录 1. 常用注解 TableName TableId TableField 2. IdType 枚举 3. 使用 TableField 的常见场景 4. 完整示例 5. 总结 在使用 MyBatis-Plus 的过程中&#xff0c;我们经常会用到一些注解来完成实体类与数据库表字段之间的映射关系。本文将带你快速入门&#xff0c;了解…

2025-08-23Excel 条件高亮工具,秒高亮显示符合筛选条件的行数据

Excel 条件高亮工具&#xff0c;秒高亮显示符合筛选条件的行数据 先看图【加班终结者】Excel 条件高亮工具&#xff08;试用版&#xff09; ——让错误数据一秒现形&#xff0c;免费先爽 30 次&#xff01; 你是不是也这样&#xff1f; • 财务对账&#xff0c;1000 行工资表里…

vue 一键打包上传

npm run build之后&#xff0c;将dist文件夹自动压缩&#xff0c;通过ssh自动连接服务器&#xff0c;把压缩包放到指定目录下&#xff0c;然后自动解压根目录创建gulpfile.js文件const gulp require(gulp); const GulpSSH require(gulp-ssh); const archiver require(archiv…

【Qt调试】无法查看QString内容

环境Qt版本&#xff1a;6.9.1问题Qt creator进入断点&#xff0c;Expressions不能查看变量&#xff08;类型&#xff1a;QString&#xff09;的内容。解决方法选择变量右键&#xff0c;勾选【Use Debugging Helpers】

防爆自动气象监测设备:高危环境的 “安全堡垒”

防爆自动气象监测设备&#xff1a;高危环境的 “安全堡垒” 柏峰【BF-FB】在化工园区、油气田、矿山等高危行业领域&#xff0c;丝毫马虎不得。而气象条件&#xff0c;这个看似平常的因素&#xff0c;实则在安全生产中扮演着举足轻重的角色。防爆自动气象监测设备的出现&#x…

《C++进阶:引用补充、内联函数与nullptr 核心用法》

&#x1f618;个人主页&#xff1a;Cx330❀ &#x1f440;个人简介&#xff1a;一个正在努力奋斗逆天改命的二本觉悟生 &#x1f4d6;个人专栏&#xff1a;《C语言》《LeetCode刷题集》《数据结构-初阶》《C知识分享》 &#x1f31f;人生格言&#xff1a;心向往之行必能至 前言…

通过python程序将实时监测数据写入excel软件进行保存是常用和非常实用的功能,本文教会大家怎么去搞定此功能

目录 一、功能介绍 二、具体的程序示例 三、实际应用建议 一、功能介绍 本方案的核心功能是持续监听一个数据源&#xff08;如传感器、API接口、消息队列、其他应用程序等&#xff09;&#xff0c;将获取到的实时数据流以追加的方式写入到Excel文件中。同时&#xff0c;方案…