详细分析Python中的unittest测试框架

目录

  • 1. 基本知识
  • 2. API
    • 2.1 断言
    • 2.2 setUp() 和 tearDown()
  • 3. Demo

1. 基本知识

unittest 是 Python 标准库中的一个单元测试框架,用于编写和执行测试用例以验证代码的正确性

提供了一种结构化的方法来编写测试,使得测试代码更加模块化和易于维护

以下是对 unittest 的详细分析和示例:

概念:

  • 测试用例(Test Case):测试代码的最小单元,通常对应于要测试的函数、方法或类的特定行为或功能
    测试用例是独立的,不依赖于其他测试用例的执行顺序

  • 测试套件(Test Suite):一组相关的测试用例的集合
    可以使用测试套件来组织和运行一系列相关的测试

  • 测试运行器(Test Runner):用于执行测试用例或测试套件的组件
    unittest 提供了一个默认的测试运行器来运行测试

  • 断言(Assertion):在测试用例中用于判断实际结果与预期结果是否相符的表达式
    如果断言失败,测试用例将会失败

  • 设置(Setup)和清理(Teardown):在执行测试用例之前或之后执行的代码
    使用 setUp() 方法在每个测试用例执行前进行设置操作
    使用 tearDown() 方法在每个测试用例执行后进行清理操作

作用:

  • 自动化测试:通过编写测试用例,可以自动化地验证代码的正确性,提高代码的质量和稳定性
  • 回归测试:在修改或更新代码后,可以运行测试用例来确保修改不会破坏现有功能
  • 文档化:测试用例也可以作为代码的文档,说明每个函数或方法应该如何被正确使用

2. API

在编写单元测试时,通常会遵循一些规范和最佳实践,以确保测试的可读性、可维护性和准确性

以下是一些常见的单元测试规范要求:

  1. 测试用例命名规范:测试用例的命名应该清晰明了,描述被测试函数或方法的行为
    通常采用test_<functionality>的命名方式,例如test_add_positive_numberstest_add_negative_numbers

  2. 测试用例设计完整性:每个测试用例应该独立、完整地测试一个特定的行为或情况
    不要在一个测试用例中测试多个不相关的行为

  3. 测试用例覆盖率:尽可能覆盖被测试代码的各种情况,包括边界情况、异常情况等

  4. 断言选择:选择适当的断言来验证测试结果
    常见的断言包括assertEqualassertTrueassertFalse

  5. 测试组织结构:通常测试用例会被组织成一个测试类,每个测试方法对应一个测试用例
    在Python中,通常使用unittest模块来实现单元测试,可以通过继承unittest.TestCase来创建测试类

2.1 断言

以下是几个常见的断言及其使用方式:

  • assertEqual(expected, actual):用于验证预期值和实际值是否相等
import unittest

class TestExample(unittest.TestCase):
    def test_addition(self):
        result = 2 + 2
        self.assertEqual(result, 4)

if __name__ == '__main__':
    unittest.main()
  • assertTrue(condition):用于验证条件是否为True
import unittest

class TestExample(unittest.TestCase):
    def test_positive_number(self):
        result = 10
        self.assertTrue(result > 0)

if __name__ == '__main__':
    unittest.main()
  • assertFalse(condition):用于验证条件是否为False
import unittest

class TestExample(unittest.TestCase):
    def test_negative_number(self):
        result = -10
        self.assertFalse(result > 0)

if __name__ == '__main__':
    unittest.main()
  • assertRaises(exception, callable, *args, **kwargs):用于验证是否会引发特定的异常
import unittest

def divide(x, y):
    return x / y

class TestExample(unittest.TestCase):
    def test_divide_by_zero(self):
        with self.assertRaises(ZeroDivisionError):
            divide(1, 0)

if __name__ == '__main__':
    unittest.main()

这些断言方法之间的区别在于它们用于验证的条件以及验证的方式

  • assertEqual用于检查值是否相等
  • assertTrueassertFalse用于检查条件是否为True或False
  • assertRaises用于验证是否引发了特定的异常

在编写单元测试时,根据需要选择最适合场景的断言方法,以确保测试的准确性和可读性

2.2 setUp() 和 tearDown()

setUp()tearDown()unittest框架中的两个特殊方法,用于在测试用例执行前后进行设置和清理操作

它们的作用是确保测试用例在独立的环境中执行,从而保证测试的可靠性和可重复性

  • setUp()
    ~ 在每个测试用例执行前进行设置操作,例如初始化对象、创建临时文件或者建立数据库连接等
    ~ 这个方法可以在测试用例的每次执行前,提供一个统一的环境,以确保测试用例在相同的初始条件下执行。如果测试用例需要共享一些设置,setUp() 是一个很好的地方来定义它们,这样可以避免在每个测试用例中重复代码
  • tearDown()
    ~ 在每个测试用例执行后进行清理操作,例如关闭文件、释放资源或者关闭数据库连接等
    ~ 可以确保在测试用例执行后,环境得到适当的清理,以避免测试用例之间的相互影响。如果在 setUp() 中进行了一些设置,需要在 tearDown() 中进行相应的清理,以确保环境的恢复

示例代码:

import unittest

class MyTestCase(unittest.TestCase):
    def setUp(self):
        # 设置操作,例如初始化对象
        self.my_list = [1, 2, 3]

    def tearDown(self):
        # 清理操作,例如释放资源
        del self.my_list

    def test_list_append(self):
        self.my_list.append(4)
        self.assertEqual(self.my_list, [1, 2, 3, 4])

    def test_list_remove(self):
        self.my_list.remove(2)
        self.assertEqual(self.my_list, [1, 3])

if __name__ == '__main__':
    unittest.main()
  • setUp() 方法用于在每个测试用例执行前初始化了一个列表 self.my_list
  • tearDown() 方法用于在每个测试用例执行后清理了这个列表

两个测试方法 test_list_append()test_list_remove() 分别对这个列表执行了添加和删除操作,并通过断言来验证操作的正确性
setUp()tearDown() 方法确保了每个测试方法在独立的环境中执行,不会相互影响。

3. Demo

通过简易的Demo熟悉这个库的基本用法

import unittest

def add(x, y):
    return x + y

class TestAddFunction(unittest.TestCase):
    
    def test_add_positive_numbers(self):
        self.assertEqual(add(1, 2), 3)
        self.assertEqual(add(0, 0), 0)
        self.assertEqual(add(-1, 1), 0)
    
    def test_add_negative_numbers(self):
        self.assertEqual(add(-1, -1), -2)
        self.assertEqual(add(-5, -7), -12)

if __name__ == '__main__':
    unittest.main()

截图如下:

在这里插入图片描述

对应如果修改某个参数,让程序报错,截图如下:

在这里插入图片描述

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

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

相关文章

【kubernetes】二进制部署k8s集群之cni网络插件flannel和calico工作原理(中)

↑↑↑↑接上一篇继续部署↑↑↑↑ 目录 一、k8s集群的三种接口 二、k8s的三种网络模式 1、pod内容器之间的通信 2、同一个node节点中pod之间通信 3、不同的node节点的pod之间通信 Overlay Network VXLAN 三、flannel网络插件 1、flannel插件模式之UDP模式&#xff0…

在 Windows 上使用 VC++ 编译 OpenSSL 源码的步骤

在 Windows 上使用 VC 编译 OpenSSL 源码的步骤如下&#xff1a; 准备工作 安装 Visual Studio 2017 或更高版本。安装 Perl 脚本解释器。安装 NASM 汇编器。 编译步骤 下载 OpenSSL 源码。解压 OpenSSL 源码。打开命令行工具&#xff0c;并进入 OpenSSL 源码目录。运行以下…

核密度分析

一.算法介绍 核密度估计&#xff08;Kernel Density Estimation&#xff09;是一种用于估计数据分布的非参数统计方法。它可以用于多种目的和应用&#xff0c;包括&#xff1a; 数据可视化&#xff1a;核密度估计可以用来绘制平滑的密度曲线或热力图&#xff0c;从而直观地表…

[HTML]Web前端开发技术27(HTML5、CSS3、JavaScript )JavaScript基础——喵喵画网页

希望你开心&#xff0c;希望你健康&#xff0c;希望你幸福&#xff0c;希望你点赞&#xff01; 最后的最后&#xff0c;关注喵&#xff0c;关注喵&#xff0c;关注喵&#xff0c;佬佬会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的…

C++力扣题目 647--回文子串 516--最长回文子序列

647. 回文子串 力扣题目链接(opens new window) 给定一个字符串&#xff0c;你的任务是计算这个字符串中有多少个回文子串。 具有不同开始位置或结束位置的子串&#xff0c;即使是由相同的字符组成&#xff0c;也会被视作不同的子串。 示例 1&#xff1a; 输入&#xff1a…

Velocity

引入 <dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>2.3</version> </dependency> 加载 Test public void velo01() throws IOException {// 设置velocity资…

Flutter插件开发指南01: 通道Channel的编写与实现

Flutter插件开发指南01: 通道Channel的编写与实现 视频 https://www.bilibili.com/video/BV1ih4y1E7E3/ 前言 本文将会通过一个加法计算&#xff0c;来实现 Channel 的双向通讯&#xff0c;让大家有个一个体会。 Flutter插件 Flutter插件是Flutter应用程序与原生平台之间的桥…

测试环境搭建整套大数据系统(六:搭建sqoop)

一&#xff1a;下载安装包 https://archive.apache.org/dist/sqoop/ 二&#xff1a;解压修改配置。 tar -zxvf sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz -C /opt cd /opt mv sqoop-1.4.7.bin__hadoop-2.6.0/ sqoop-1.4.7修改环境变量 vi /etc/profile#SQOOP_HOME export SQOOP_…

远程连接 vscode 出错 “远程主机可能不符合 glibc 和 libstdc++ VS Code 服务器的先决条件”

原因&#xff1a; vscode 版本是 1.86&#xff0c;服务器上的 glibc 和 libstdc 版本不满足 要求(2.28 和 3.4.25)。 解决&#xff1a; 1、下载 1.85.2&#xff0c;解压直接运行 Code.exe。 2、回退 Remote-ssh 到 0.107.1。 参考&#xff1a; vscode 1.86版本远程ssh不兼容旧…

关于运行flutter app 运行到模拟器出现异常提示

Exception: Gradle task assembleDebug failed with exit code 1 解决方案&#xff1a; 1.讲当前文件的distributionUrl值改为 https://mirrors.cloud.tencent.com/gradle/gradle-7.4-all.zip

【论文解读】Uncertainty Quantification of Collaborative Detection for Self-Driving

Uncertainty Quantification of Collaborative Detection for Self-Driving 摘要引言方法问题定义方法概览Double-M 实验结论 摘要 在联网和自动驾驶汽车(CAVs)之间共享信息从根本上提高了自动驾驶协同目标检测的性能。然而&#xff0c;由于实际挑战&#xff0c;CAV 在目标检测…

$attrs

一、概念 vue官网定义如下: 包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过v-bind="$attrs"传入内部组件——在创建…

C语言翻译环境:预编译+编译+汇编+链接详解

目录 翻译环境和运行环境 翻译环境 预处理&#xff08;预编译&#xff09; 编译 词法分析 语法分析 语义分析 汇编 链接 运行环境 ⭐翻译环境和运行环境 在ANSI C的任何⼀种实现中&#xff0c;存在两个不同的环境。 第1种是翻译环境&#xff0c;在这个环境中源代码被…

Java并发基础:原子类之AtomicIntegerFieldUpdater全面解析

本文概要 AtomicIntegerFieldUpdater类提供了一种高效、简洁的方式来原子性地更新对象的volatile字段&#xff0c;无需使用重量级的锁机制&#xff0c;它通过基于反射的API实现了细粒度的并发控制&#xff0c;提升了多线程环境下的性能表现。 AtomicIntegerFieldUpdater核心概…

选择VR全景行业,需要了解哪些内容?

近年来&#xff0c;随着虚拟现实、增强现实等技术的持续发展&#xff0c;VR全景消费市场得以稳步扩张。其次&#xff0c;元宇宙行业的高速发展&#xff0c;也在进一步拉动VR全景技术的持续进步&#xff0c;带动VR产业的高质量发展。作为一种战略性的新兴产业&#xff0c;国家和…

【vue vue-seamless-scroll】解决vue-seamless-scroll鼠标悬浮才滚动或者只滚动一次就失效的问题

解决问题&#xff1a;使用vue-seamless-scroll发现只有鼠标悬浮上去才滚动&#xff0c;而且滚动一次停止了 目标效果&#xff1a; 解决方案&#xff1a; 最后发现是因为数据需要在页面挂载好就赋值&#xff0c;否则页面在加载完成后&#xff0c;数据无法自动滚动。但因为数据…

防火墙内容安全笔记

目录 DFI和DPI IDS和IPS 签名 AV URL过滤 HTTPS过滤 内容过滤 文件类型过滤 文件内容过滤 邮件过滤 VPN概述 DFI和DPI DFI和DPI技术 --- 深度检测技术 DPI DPI --- 深度包检测技术 --- 主要针对完整的数据包&#xff08;数据包分片&#xff0c;分段需要重组&#…

百亿美金的设计,深度剖析 GitLab 的 Postgres 数据库 schema

原文链接 这篇文章写于 2022 年&#xff0c;前一年 GitLab 刚好完成 IPO。目前 GitLab 市值超过 100 亿美金&#xff0c;它的所有收入都来源于同名产品 GitLab&#xff0c;而这篇文章就是全面分析 GitLab 这个产品的数据库 schema。 我花了一些时间研究 GitLab 的 Postgres sch…

【ArcGIS Pro二次开发】(82):玩个花活_控规指标块生成

一、要实现的效果 废话不多说&#xff0c;这次要实现的是类似控规指标块的标注&#xff1a; 这里只是示例&#xff0c;用了5个格子&#xff0c;做成9个格子也是可以的。 实现这个效果最关键的是要用到Pro中的复合标注。 关于复合标注的用法可以搜一下帮助里的【使用复合注释…

网站常见的攻击类型有什么,如何针对性防护

在互联网时代&#xff0c;几乎每个网站都存在着潜在的安全威胁。这些威胁可能来自人为失误&#xff0c;也可能源自网络犯罪团伙所发起的复杂攻击。无论攻击的本质如何&#xff0c;网络攻击者的主要动机通常是谋求经济利益。这意味着不管是什么网站类型潜在的威胁一直都存在。 在…