自动化测试系列 之 Python单元测试框架unittest

news2025/4/23 18:27:57

一、概述

什么是单元测试

单元测试是一种软件测试方法,是测试最小的可测试单元,通常是一个函数或一个方法。

在软件开发过程中,单元测试作为一项重要的测试方法被广泛应用。

为什么需要单元测试

单元测试是软件开发中重要的一环,具有以下作用:

  1. 验证代码的正确性:单元测试可以自动化地验证代码的正确性,避免开发人员手动测试时漏掉某些情况或错误。通过单元测试,可以及时发现和定位代码中的错误,并保障代码质量和缺陷率。
  2. 更好地组织和维护代码:通过单元测试,代码将被分割为小的可测试单元,每一个单元都有对应的测试用例,更好地组织代码,增加代码的可读性和可维护性。
  3. 提高开发效率:单元测试的快速执行和反馈,可以有助于开发人员快速找到问题并迅速地解决它们。这样可以加快迭代速度,提高软件开发效率。
  4. 自信心:通过单元测试,开发人员可以自信地修改和重构现有的代码,因为单元测试可以保证代码质量和正确性,减少犯错的机会。
Python 中的单元测试框架

各种编程语言都有自己的单元测试框架,Python中主流的单元测试框架包括:

  1. unittest: Python自带的单元测试框架,是xUnit风格的测试框架。
  2. pytest: 一个第三方的Python单元测试框架,具有更好的扩展性和灵活性。pytest具有更好的预期错误展示和简化测试用例编写的特点。
  3. nose: 另一个第三方的Python单元测试框架,它具有可插拔的插件架构,可以轻松地扩展其功能。
  4. doctest: Python自带的另一个单元测试框架,可以在Python代码中使用文档字符串编写测试用例
  5. Testify: 一个相对较新的Python单元测试框架,专注于在类与海量测试用例下提供更快速的速度和更好的效率。

本文将着重介绍Python自带的带有测试皇家 unittest

二、unittest框架介绍

unittest框架的背景和产生

unittest 是一个Java单元测试框架 JUnit 的Python版本。unittest最初由Python的核心开发者Tim Peters在2001年开发,旨在提供一种规范的方式来编写单元测试,以改进传统的debugging因试错所造成的时延。

unittest框架的特点与优势

unittest框架有以下特点与优势:

  • 标准化的测试工具: unittest框架提供了标准化的测试工具和从标准TestCase集成的测试运行器,为新手和高级用户提供了一个可用的接口。
  • 支持自动化测试: 可以通过编写自动化测试用例,加快测试效率,缩短测试时间,减少人工测试工作。
  • 支持测试定制: unittest框架可以轻松集成第三方库,支持创建自定义的测试用例和测试套件。
  • 执行结果明确: unittest框架提供了详细的错误信息,让测试人员能够快速地定位和修复错误。

三、unittest框架基础

安装和配置unittest框架

unittest是Python的内置模块,所以你不需要额外安装。

unittest 简单示例

被测试的代码demo,包含了两个方法, addsub

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def add(a, b):
    return a + b

def sub(a, b):
    return a - b

为这两个函数编写单元测试用例

import unittest
from calculate import add, sub

class TestCalcuate(unittest.TestCase):
    def test_add(self):
        result = add(2, 3)
        self.assertEqual(result, 5) 

    def test_sub(self):
        result = sub(5, 3)
        self.assertEqual(result, 2)

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

在这个测试用例中,我们导入了addsub函数,并创建了一个名为 TestCalcuate 的测试类(所有的测试类都必须是unittest.TestCase 的子类)。在这个类中,我们定义了两个测试方法test_addtest_sub,分别用于测试加法和减法函数的行为。

在每个测试方法中,我们调用相应的函数,并使用self.assertEqual断言方法来验证计算结果是否等于预期值。

最后,我们使用unittest.main()来运行测试用例。

四、unittest框架常用的测试类和方法

Python的unittest框架中,提供了许多用于辅助构建单元测试的类和方法

常用的测试类
  1. unittest.TestCase:这是unittest框架中最重要的测试类,所有的测试用例都应该继承自它。它提供了一些常用的断言方法和测试辅助方法,用于编写和运行测试。
  2. unittest.TestSuite:这个类用于组织和管理一组测试用例。你可以将多个测试用例添加到一个测试套件中,并一次性运行它们。
  3. unittest.TestLoader:这个类用于加载测试用例。它提供了一些方法,可以从模块、类或者目录中自动发现和加载测试用例。
  4. unittest.TextTestRunner:这个类用于运行测试用例并生成测试结果的文本报告。它提供了一些方法,可以控制测试的输出格式和详细程度。
  5. unittest.TestResult:这个类用于存储测试结果。它提供了一些方法,可以获取测试的状态、错误信息和失败信息等。
常用的方法

在unittest框架中,常用的方法包括setUp()tearDown()setUpClass()tearDownClass()。这些方法用于在测试用例的执行过程中进行准备和清理工作。

  1. setUp()方法:在每个测试方法运行之前调用。它用于准备测试环境,例如初始化对象、打开文件等。每个测试方法都会在调用setUp()方法后执行。
  2. tearDown()方法:在每个测试方法运行之后调用。它用于清理测试环境,例如关闭文件、释放资源等。每个测试方法都会在调用tearDown()方法后执行。
  3. setUpClass()方法:在测试类中的所有测试方法运行之前调用。它用于进行一次性的测试环境准备工作,例如连接数据库、启动服务器等。setUpClass()方法需要使用@classmethod装饰器进行标记。
  4. tearDownClass()方法:在测试类中的所有测试方法运行之后调用。它用于进行一次性的测试环境清理工作,例如断开数据库连接、关闭服务器等。tearDownClass()方法需要使用@classmethod装饰器进行标记。

这些方法可以在测试类中重写,并根据需要进行自定义操作。

五、编写测试用例

当使用unittest框架编写测试用例时,通常需要进行以下步骤:

  1. 创建测试用例:
    • 创建一个继承自unittest.TestCase的测试类。
    • 在测试类中定义一个或多个测试方法。每个测试方法应该以test_开头,以便unittest能够自动识别并运行它们。
    • 在每个测试方法中,编写测试逻辑并使用断言方法来验证结果是否符合预期。
  2. 管理测试用例:
    • 使用unittest.TestLoader类来加载测试用例。你可以使用loadTestsFromModule()方法从模块中加载测试用例,或者使用loadTestsFromTestCase()方法从测试类中加载测试用例。
    • 创建一个unittest.TestSuite对象,并将加载的测试用例添加到测试套件中。你可以使用addTest()方法添加单个测试用例,或者使用addTests()方法添加多个测试用例。
  3. 运行测试用例:
    • 使用unittest.TextTestRunner类来运行测试用例并生成测试结果的文本报告。
    • 创建一个unittest.TextTestRunner对象。
    • 调用run()方法运行测试套件,并将结果输出到控制台或文件中。

结合前面的例子,进一步演示如何编写、管理和运行测试用例:

import unittest

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

    def test_sub(self):
        result = 5 - 3
        self.assertEqual(result, 2)

if __name__ == '__main__':
    # 创建测试套件并添加测试用例
    suite = unittest.TestSuite()
    suite.addTest(MyTestCase('test_add'))
    suite.addTest(MyTestCase('test_sub'))

    # 创建测试运行器并运行测试套件
    runner = unittest.TextTestRunner()
    runner.run(suite)

在这个示例中,我们创建了一个名为MyTestCase的测试类,并在其中定义了两个测试方法test_addtest_sub。然后,我们创建了一个测试套件,并使用addTest()方法将测试用例添加到测试套件中。最后,我们创建了一个测试运行器,并使用run()方法运行测试套件。

运行这个示例,你将看到测试结果的输出。如果所有测试通过,你将看到一个成功的消息。如果有测试失败,你将看到失败的消息和详细的错误信息。

这是使用unittest编写、管理和运行测试用例的基本步骤。你可以根据需要编写更多的测试方法,并使用各种断言方法来验证你的代码的行为。

六、unittest常用的断言方法

以下是unittest常用的断言方法以markdown表格的方式呈现:

断言方法

描述

assertEqual(a, b)

断言a和b相等

assertNotEqual(a, b)

断言a和b不相等

assertTrue(x)

断言x为True

assertFalse(x)

断言x为False

assertIs(a, b)

断言a和b是同一个对象

assertIsNot(a, b)

断言a和b不是同一个对象

assertIsNone(x)

断言x为None

assertIsNotNone(x)

断言x不为None

assertIn(a, b)

断言a在b中

assertNotIn(a, b)

断言a不在b中

assertIsInstance(a, b)

断言a是b的实例

assertNotIsInstance(a, b)

断言a不是b的实例

assertRaises(exception, callable, *args, **kwargs)

断言调用callable(*args, **kwargs)会引发指定的异常

assertWarns(warning, callable, *args, **kwargs)

断言调用callable(*args, **kwargs)会引发指定的警告

assertLogs(logger=None, level=None)

断言在指定的日志记录器上发生了指定级别的日志记录

assertAlmostEqual(a, b, places=None, msg=None, delta=None)

断言a和b近似相等

assertNotAlmostEqual(a, b, places=None, msg=None, delta=None)

断言a和b不近似相等

assertSequenceEqual(a, b, msg=None, seq_type=None)

断言a和b是相同的序列

assertListEqual(a, b, msg=None)

断言a和b是相同的列表

assertTupleEqual(a, b, msg=None)

断言a和b是相同的元组

assertSetEqual(a, b, msg=None)

断言a和b是相同的集合

assertDictEqual(a, b, msg=None)

断言a和b是相同的字典

这些断言方法可以根据需要选择合适的方法来编写测试用例,并验证代码的行为是否符合预期。

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

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

相关文章

HackTheBox - Medium - Linux - Interface

Interface Interface 是一种中等难度的 Linux 机器,具有“DomPDF”API 端点,该端点通过将“CSS”注入处理后的数据而容易受到远程命令执行的影响。“DomPDF”可以被诱骗在其字体缓存中存储带有“PHP”文件扩展名的恶意字体,然后可以通过从其…

前端开发工具之HBuilder X

HBuilderX(简称HX)是一款由DCloud开发的集成开发环境(IDE),专为前端开发者设计。它不仅是一个编辑器,也可以看作是一个通用的IDE,类似于VSCode、Sublime和WebStorm。HBuilderX支持开发各种Web项…

论文阅读——EfficientViT(cvpr2023)

EfficientViT: Memory Efficient Vision Transformer with Cascaded Group Attention 1、 从三个角度探讨如何提高vision transformers的效率:内存访问、计算冗余和参数使用。 2.1. Memory Efficiency 红色字体表示操作所花费的时间主要由内存访问决定,…

RSA加密解密——用shell加密java解密

功能描述 使用shell opensll对明文进行RSA加密,将密文用java的RSA工具对密文解密。这应该是全网第一个同时用到shell和java的RSA加密解密教程。中间有很多坑,都踩过了,可以放心使用代码。 正确的实现流程 shell端 首先生成公钥私钥 &…

C/C++ 对象、继承和引用

ostream和ofstream类凸现了引用的一个有趣属性。正如ofstream 对象可以使用 ostream类的方法,这使得文件输入/输出的格式与控制台输入/输出相同。使得能够将特性从一个类传递给另一个类的语言特性被称为继承。 简单地说,ostream 是基类,而ofs…

<软考高项备考>《论文专题 - 37 采购管理(1) 》

1 成本管理基础 1.1 写作要点 过程定义、作用写作要点、思路规划采购管理规划采购管理是记录项目采购决策、明确采购方法,及识别潜在卖方的过程。作用:确定是否从项目外部获取货物和服务,如果是,则还要确定将在什么时间、以什么方式获取什么…

OSPF的DR与BDR-新版(16)

目录 整体拓扑 操作步骤 1.基本配置 1.1 配置R1的IP 1.2 配置R2的IP 1.3 配置R3的IP 1.4 配置R4的IP 1.5 检测R1与R4连通性 1.6 检测R1与R2连通性 1.7 检测R1与R3连通性 2.搭建基本的OSPF网络 2.1 配置R1 OSPF 2.2 配置R2 OSPF 2.3 配置R3 OSPF 2.4 配置R4 OSPF…

力扣刷题总结 栈与队列

🔥博客主页: A_SHOWY🎥系列专栏:力扣刷题总结录 数据结构 云计算 数字图像处理 力扣每日一题_ 一、栈和队列的基础知识 队列是先进先出,栈是先进后出。同时二者都是容器适配器而不是容器。 二、题目实战 232.用栈…

帆软报表如何灵活控制水印的显示

在帆软报表中如果要显示水印,如果要全部都要显示,只需要到决策系统--安装设置中打开水印开关。如果想要某个报表显示水印,可以在设计器的水印设置中为该报表设置水印。 但是如果碰到这种需求,比如某些人或者某些角色需要显示水印,其他人不显示。或者是预览报表需要显示水印…

conda环境下face_alignment.LandmarksType._2D AttributeError: _2D解决方法

1 问题描述 运行retalking模型时&#xff0c;代码抛出异常&#xff0c;信息如下所示&#xff1a; Traceback (most recent call last):File "D:/ml/video-retalking/inference.py", line 345, in <module>main()File "D:/ml/video-retalking/inference.…

C++初阶(类中的默认成员函数)

呀哈喽&#xff0c;我是结衣 今天给大家带来的是类里面的默认成员函数&#xff0c;一共有六个默认的成员函数哦&#xff0c;包括构造函数&#xff0c;析构函数&#xff0c;拷贝构造函数&#xff0c;运算符重载函数&#xff0c;const成员函数&#xff0c;那么正篇开始。 文章目…

【OpenCV】OpenCV 4.9.0 正式发布

​ 开源计算机视觉库 OpenCV 4.9.0 已于2023年12月29日正式发布。 此次发布有DNN模块对ONNX Attention、Einsum等层的支持、新的fastGEMM实现、transformers的实验性支持等诸多亮点。 OpenCV 4.9.0 更新内容&#xff1a; &#xff08;来自OpenCV中国团队以及中国社区的贡献…

解决Windows11安装Docker 一直starting 的办法

Starting the Docker Engine... Docker Engine is the underlying technology that runs containers 关闭docker 管理员身份执行wsl --update后在启动。 另外&#xff0c;docker desktop-unexpected wsl error问题跟标题问题好像是同一个问题&#xff0c;我的是一直让其star…

07-C++ 异常

异常 1. 概念 异常事件&#xff08;如&#xff1a;除 0 溢出&#xff0c;数组下标越界&#xff0c;所要读取的文件不存在,空指针&#xff0c;内存不足等等&#xff09; 在C 语言对错误的处理是两种方法&#xff1a; 一是使用整型的 返回值标识错误&#xff1a;二是使用 errno…

自创题目——贴对联

预估难度 简单 题目描述 小明家最近要挂对联&#xff0c;小明要知道对联怎么挂&#xff0c;以及对联合不合规。如果不合规&#xff0c;输出"扔了吧"&#xff0c;否则输出&#xff1a; 横批 ... ... 输入格式 共三行&#xff1b; 第一行&#xf…

MySQL入门教程-函数,索引

4MySQL函数 常用函数 -- 数学运算SELECT ABS(-8); -- 绝对值SELECT CEIL(5.1); -- 向上取整SELECT CEILING(5.1); -- 向上取整SELECT RAND(); -- 返回0~1之间的一个随机数SELECT SIGN(-10); -- 返回一个数的符号;0返回0;正数返回1;负数返回-1​-- 字符串函数SELECT CHAR_LENGT…

树低级(C语言版)

一.树基本计算规则 关于树的大部分知识点我们都讲过了&#xff0c;那么如果我给你树的节点&#xff0c;你可以算出叶子节点个数吗&#xff1f; 下面我们总结下一些计算规则&#xff1a; 1.父子计算规则&#xff1a; parent(child-1)/2; leftchildparent*21,rightchildpare…

swing快速入门(三十三)确认对话框

注释很详细&#xff0c;直接上代码 新增内容 1.确定对话框返回值对应值 2.为文本域增加滚动条 package swing31_40;import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent;public class swing_test_31 {// 创建一个JFrameJFrame jFrame new JFrame(…

《现代操作系统》第十二章习题答案

计算机硬件的改进主要归功于更小的晶体管。一些限制因素包括&#xff1a;(a) 光的波动性可能限制传统光刻技术制造集成电路的能力&#xff0c;(b) 固体中个别原子的迁移性可能导致非常薄的半导体、绝缘体和导体层的性能退化&#xff0c;(c) 背景辐射活性可能破坏分子键或影响非…

pytorch01:概念、张量操作、线性回归与逻辑回归

目录 一、pytorch介绍1.1pytorch简介1.2发展历史1.3pytorch优点 二、张量简介与创建2.1什么是张量&#xff1f;2.2Tensor与Variable2.3张量的创建2.3.1 直接创建torch.tensor()2.3.2 从numpy创建tensor 2.4根据数值创建2.4.1 torch.zeros()2.4.2 torch.zeros_like()2.4.3 torch…