Python 单元测试

Python单元测试之道:从入门到精通 单元测试是软件开发中不可或缺的一部分,有助于确保代码的正确性、可维护性和可扩展性。在Python中,有丰富的工具和库可用于进行单元测试。 阅读详情

软件测试即是一种实际输出与预期输出间的审核或者比较过程

什么是单元测试

  1. 什么是单元

    代码逻辑中的最小可复用部分:类、函数等

  2. 单元测试的目标

    详细验证所有(一般以代码覆盖率为指标)实现代码的执行逻辑,尤其是各种边界条件

为什么要写单元测试

程序单元作为应用的最小可测试部件。测试能够保证程序的强壮性,也能促使重新思考代码的设计,避免写出耦合严重的代码。

简单来说,就是能够确保代码质量,能够帮助我们较早地发现 Bug;能够改善代码设计,难以测试的代码一般是设计不够简洁的代码;保证重构不会引入新问题,每次修改之前代码的时候,只需重新跑测试代码就能避免新改动的代码对现有代码产生影响。

何时进行单元测试

  • 扩展实现代码时(实现新功能时)
  • 修改现有代码时(代码重构)
  • 任何代码提交时(CI)

如何保证单元测试的隔离性

  1. 单元测试的隔离性问题

    一般我们写的代码,常基于别人的 API 代码构建,同时,我们的代码也常作为别人的 API 代码被调用。在进行单元测试时,实际外部依赖可能包含复杂计算或者存在网络请求,成本较高,不适合重复执行。例如,我们代码依赖的 API 并没有被实现和被提供,比如我们的代码作为C/S模式中的客户端依赖服务端的某个 HTTP 服务;或者,我们的代码运行时可能会对周围代码产/生负面影响,比如发送一个修改数据库数据、发送电子邮件,显然不适合每次执行都真实地进行这些数据修改或者网络请求。

  2. 如何保证单元测试的隔离性

  • 使用 Mock/Stub/Fake 替换外部依赖
  • 指定替换逻辑的行为
  • 验证带测试逻辑的行为

Python 单元测试相关包

  • unittest: Python 内置库,优点是简洁易用,缺点是使用时比较繁琐
  • pytest:上手容易,使用起来简洁高效
  • mock: 替换掉网络调用或者 rpc 请求等

例子

下面是一个关于几何圆的代码单元测试例子,以说明单元测试在修改现有代码时的作用。

  1. 圆的实现代码 (circle.py)

    # -*- coding: utf-8 -*-
    # @File    : circle.py
    from math import pi
    # pi = 3.14 # 后面会修改代码所依赖的 PI 的值,并进行单元测试
    
    class Circle(object):
        """docstring for Circle"""
    
        def __init__(self, radius):
            super(Circle, self).__init__()
            self.radius = radius
    
        @property
        def diameter(self):
            """
            圆的直径
            :return:  直径
            """
            return 2 * self.radius
    
        @diameter.setter
        def diameter(self, value):
            """
            设置直径
            :param value: 直径的值
            :return: None
            """
            self.radius = value / 2.0
    
        @diameter.deleter
        def diameter(self):
            raise AttributeError("Can't delete attribute")
    
        @property
        def perimeter(self):
            """
            圆的周长
            :return: 周长
            """
            return 2 * pi * self.radius
    
        @perimeter.setter
        def perimeter(self, value):
            self.radius = value / pi / 2.0
    
        @perimeter.deleter
        def perimeter(self):
            raise AttributeError("Can't delete attribute")
    
        @property
        def area(self):
            """
            圆的面积
            :return: 面积
            """
            return pi * (self.radius ** 2)
    
        @area.setter
        def area(self, value):
            self.radius = (value / pi) ** (1 / 2)
    
        @area.deleter
        def area(self):
            raise AttributeError("Can't delete attribute")
    
    
    def print_circle_info(c1):
        print("radius: {}".format(c1.radius))
        print("diameter: {}".format(c1.diameter))
        print("perimeter: {}".format(c1.perimeter))
        print("area: {}".format(c1.area))
    
    
    if __name__ == '__main__':
        c1 = Circle(1)
        print_circle_info(c1)
    
        print("\n================")
        print("set diameter to 4")
        print("================")
        c1.diameter = 4
        print_circle_info(c1)
    
        print("\n================")
        print("set perimeter to 6.28")
        print("================")
        c1.perimeter = 6.28
        print_circle_info(c1)
    
  2. 单元测试代码 ( test_circle_pytest.py )

    # -*- coding: utf-8 -*-
    # @File    : test_circle_pytest.py
    import pytest
    
    from circle import Circle
    
    
    class TestCirclePytest:
        def test_init(self):
            c0 = Circle(1)
            assert c0.radius == 1
    
        def test_diameter(self):
            c0 = Circle(2)
            assert c0.diameter == 4
    
            c0.diameter = 8
            assert c0.diameter == 8
    
            with pytest.raises(AttributeError):
                del c0.diameter
    
        def test_perimeter(self):
            c0 = Circle(1)
            assert c0.perimeter - 6.28318 == pytest.approx(0, abs=1E-5)
    
            c0.perimeter = 6.28
            assert c0.perimeter == 6.28
            assert abs(c0.radius - 1.0) == pytest.approx(0, abs=0.01)
    
            with pytest.raises(AttributeError):
                del c0.perimeter
    
        def test_area(self):
            c0 = Circle(1)
            assert c0.area - 3.14159 == pytest.approx(0, abs=1E-5)
    
            c0.area = 3.14
            assert c0.area == 3.14
    
            with pytest.raises(AttributeError):
                del c0.area
    
  3. 代码实现后的单元测试结果

    unittest

    代码实现后,运行单元测试代码,显然,结果显示代码实现基本没问题

  4. 修改代码中的某些部分

    实际写代码的时候,总会因为某些需求,会需要修改现已实现的代码。为了模拟,这种需求,这里我们修改代码所依赖的 PI 值。修改 circle.py 中的 PI 值为 3.14 :

    # -*- coding: utf-8 -*-
    # @File    : circle.py
    # from math import pi  # 去掉之前的 PI 值的定义
    pi = 3.14
    
    其他代码省略 ...
    
  5. 修改代码后重新运行单元测试代码

unittest2
从运行结果可以看到,修改 pi 的值后,单元测试中部分测试样例没有通过,分析可以发现,主要是因为 pi 值的精度达不到我们测试代码的要求。将 PI 值修改为 3.141592526 显然就可以,甚至可以一点点增加 PI 的精度,直到通过单元测试。

参考链接

  1. Python 单元测试 —— 知乎

  2. 单元测试 —— 廖雪峰的个人网站

    • 单元测试可以有效地测试某个程序模块的行为,是未来重构代码的信心保证。
    • 单元测试的测试用例要覆盖常用的输入组合、边界条件和异常。
    • 单元测试代码要非常简单,如果测试代码太复杂,那么测试代码本身就可能有bug。
    • 单元测试通过了并不意味着程序就没有bug了,但是不通过程序肯定有bug。
  3. python单元测试框架pytest简介 —— 优快云 博客

  4. Python测试框架 - Pytest

  5. 用 pytest 测试 python 代码

  6. Mock 在 Python 单元测试中的使用

python单元测试之unittest python单元测试之unittest 一:单元测试,集成测试,功能测试 单元测试 颗粒度最小,一般由开发小组采用白盒方式来测试,主要测试单元是否符合“设计”;是指对软件中的最小可测试单元进行检查和验证 集成测试 介于单元测试和系统测试之间,一般由开发小组采用白盒+黑盒的方法来测试,即验证“设计”又验证“需求”。主要用来测试模板与模板之间的接口,同时还要测试一些主要的业务功能。 功能测试 颗粒度最大,一般由独立的测试小组采用黑盒的方式来测试,主要测试系统是否符合“需求规格说明书 问题:什么是白盒 阅读详情

相关推荐

python单元测试怎么写_python--单元测试

1.单元测试是什么?单元测试(又称为模块测试, Unit Testing)是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。单元测试粒度最小,一般由开发人员采用白盒方式来测试,主要测试单元是否符合设计。单元测试...

weixin_42515906的博客 1556

Python测试 | 在python中创建单元测试

新钛云服已累计为您分享710篇技术干货作为开发人员或程序员, 只要编写代码,通常就会忽略一件事:测试。测试是开发的一部分,您应该严格测试应用程序,以确保它们满足必需的功能。让我们先从为什么要做测试开始:1、减少手动测试的需求因为测试用例是预先编写的,所以没有真正的理由再进行手动测试。大多数时候,特别是对于大型应用程序,您必须在软件中运行许多阶段,以测试某个特性是否有效。这可以通过测试来避免。想象一...

NewTyun的博客 3222

unittest单元测试实战

unittest 是 python 自带的一个单元测试框架,类似于 java 的 junit,基本结构是类似的。unittest 中有 5 个重要的概念:TestCase、TestSuite、TestRunner、TestLoader、TestFixtureTestcase:一个 TestCase 的实例就是一个测试用例。什么是测试用例呢?就是一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown)。

悦分享 2198

用Python进行单元测试

Python编程语言,不仅仅在机器学习、数据分析等领域大放异彩,在web开发中等软件开发中,使用者也越来越多。 在软件开发中,有一种被提倡的开发范式:测试驱动开发。在这种开发范式中,编写单元测试是必不可少的。如果不实施严格的测试驱动开发,编写单元测试程序也是必要的。 对于单元测试而言,最基本的模块是pytest,在本文中会对这个模块给予简要介绍。此外,还有一个现在很流行的模块fizz buzz,本文也会向读者推荐。 为什么要自动化测试 并非所有人都理解自动化测试的必要性,有人甚至认为纯粹是个负担,他们认为

计算机科学、人工智能、数据分析和大数据方向的研发和教学。 4889

SAP成本核算变式OKKN配置详解:从CK11N到CK24,手把手教你搞定标准成本发布

本文深入解析SAP成本核算变式OKKN的配置原理与实战应用,涵盖从CK11N到CK24的标准成本发布全流程。详细讲解数量结构控制、价值结构配置及间接费用计算规则,帮助成本会计精准掌握标准成本计算逻辑,解决BOM版本选择、工艺路线获取等常见问题,提升企业成本管理效率。

weixin_27219587的博客 289

APM 飞行模式切换--源码详解

APM飞控中有很多种方式可以改变飞行模式。其中最常见的为遥控器切换和地面站切换两种方式。 下面以遥控器切换为例详解飞行模式切换逻辑。 APM遥控器切换飞行模式的源代码在RC_Channel.cpp文件中的RC_Channel_Copter::do_aux_function_change_mode()函数中。 const bool success = copter.set_mode()调用Copter::set_mode()函数,在set_mode()函数中调用mode_fro...

qq_30623591的博客 2440

Python单元测试

Python单元测试

summerriver1的博客 2105

Zabbix监控联想服务器XCC的SNMPv3配置实战

本文详细介绍了如何通过SNMPv3协议配置Zabbix监控联想服务器XCC的实战方法。文章从安全角度阐述了选择SNMPv3的必要性,并分步讲解了在XCC中启用SNMPv3、创建认证用户,以及在Zabbix中导入专用模板、创建主机并关联模板的完整流程,帮助运维人员实现对服务器硬件健康状态的自动化、安全监控。

weixin_29210727的博客 466

Python 单元测试详解

作者:yukkizhang,腾讯 CSIG 测试工程师本文直接从常用的 Python 单元测试框架出发,分别对几种框架进行了简单的介绍和小结,然后介绍了 Mock 的框架,以及测试报告生成...

腾讯技术工程 8588

华为OD机试真题 Java&Go 实现【优雅子数组】【100%通过率】【2022.11 Q4 新题】

如果一个数组中出现次数最多的元素出现大于等于K次,被称为K -优雅数组,k也可以被称为优雅阈值。例如,数组1,2,3,1、2,3,1,它是一个3-优雅数组,因为元素1出现次数大于等于3次,数组1,2,3,1,2就不是一个3-优雅数组,因为其中出现次数最多的元素是1和2,只出现了2次。给定一个数组A和k,请求出A有多少子数组是k-优雅子数组。

MISAYAONE的博客 1万+

HTML5+CSS3+JS小实例:扇形展开折叠菜单

你肯定见过那种圆形浮动按钮(FAB),点一下弹出几个选项。大部分实现就是菜单项从底下往上"弹"出来,排成一列——能用,但没啥记忆点。后来我看到 Path 那个经典的扇形菜单,点一下,五个按钮像花瓣一样从中心散开,每个带不同的延迟和弹性曲线。当时就觉得:这才对嘛,交互就该有点"戏剧性"。今天拆一个纯手写版本,HTML + CSS + JS,不依赖任何库。六菜单项、扇形 144° 展开、弹性过渡、点击关闭、键盘可达——该有的都有。

艾恩小灰灰的博客 164

Python 面试:单元测试unit testing & 使用pytest

【代码】Python 面试:单元测试unit testing。

weixin_57266891的博客 1461

基于深度学习的推荐系统设计与实现

基于深度学习的推荐系统设计与实现 作者:禅与计算机程序设计艺术 / Zen and the Art of Computer Programming / TextGenWebUILLM 基于深度学习的推荐系统设计与实现 关键词:深度学习, 推荐系统, 用

AI天才研究院 1079

在 python 中进行单元测试

单元测试(unit test)就是编写测试来验证某一模块的功能正确性。一般会指定输入,验证输出是否符合预期。 单元测试 进行单元测试,首先要导入 unittest 库。 import unittest 先写一个功能函数,这里以完成加法为例,完成两个数的加法。 def add(a, b): return a + b 为了验证加法函数的功能是否正确,首先创建一个 TestAdd 类,继承类 unittest.TestCase,然后在这个类中定义相应的测试函数 test_add(),测试函数要以 test

算法笨蛋 8174

【自动驾驶轨迹规划之hybrid A*算法】

本文参考论文:https://ai.stanford.edu/~ddolgov/papers/dolgov_gpp_stair08.pdf 这篇文章是基于经典A*算法与reeds-shepp曲线的,不清楚的读者请参考【自动驾驶轨迹规划5之A*算法】_无意2121的博客-优快云博客【自动驾驶轨迹规划之dubins曲线与reeds-shepp曲线】_无意2121的博客-优快云博客 目录 1 hybrid A* 算法创新点 1.1 搜索方式 1.2 车辆运动学模型 1.3 reeds-shepp曲

weixin_65089713的博客 1万+

COMSOL有限元仿真深度指南:连接薄结构与实体结构(I)

COMSOL有限元仿真深度指南:如何在结构力学仿真中连接薄结构与实体结构?

忘了面孔的Batou 1万+

Python中怎么进行单元测试

既然是测试,那我们得有被测试的代码,我们先定义一个简单的函数,这个函数的功能就是接收一个姓名,并返回一句问候语句。 say_hello_function.py 1 def hello_name(name): 2 greet = "Hello , " 3 return greet + name.title() 显然,关于单元测试Python也给我们提供了相应的模块(...

桃子dev的博客 1094

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

python 单元测试_Python 单元测试

简介Python中的单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。如果你听说过“测试驱动开发”(TDD:Test-Driven Development),单元测试就不陌生。单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。比如对函数abs(),我们可以编写出以下几个测试用例:输入正数,比如1、1.2、0.99,期待返回值与输入相同;输入负数...

weixin_39669638的博客 132

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Python 单元测试:八个单元测试框架的使用方法

​ 单元测试是软件开发中不可或缺的一部分,它能够帮助开发者确保代码的质量和稳定性。Python 社区提供了多种单元测试框架,每种框架都有其独特的优势和适用场景。本文将介绍几种常见的 Python 单元测试框架,并通过实际例子帮助读者更好地理解和使用它们。 ​

hlsxjh的博客 742

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

python单元测试入门_python基础——单元测试

python基础——单元测试如果你听说过“测试驱动开发”(TDD:Test-Driven Development),单元测试就不陌生。单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。比如对函数abs(),我们可以编写出以下几个测试用例:输入正数,比如1、1.2、0.99,期待返回值与输入相同;输入负数,比如-1、-1.2、-0.99,期待返回值与输入相反;输入0,期待返回0...

weixin_39544333的博客 252

python单元测试

当你雄心勃勃的写一个大工程的时候,请在你的checklist里写下三个词语:功能函数化,模块化,单元测试。单元测试时伴随在开发过程的自我测试,开发完一个函数,单元测试一下;所以当你写完你的任务时,交给测试人员测试的时候,你心里是充满自信的。当然,你可以不需要unittest这个包,但请你创建test文件夹,创建testXXX.py来测试你的功能。如果你等完成了所有的开发,再来测试,要么来不及测试,要么测一个大概的流程,结果是测试人员无休止的找你。上面的例子,我们要测试类的Func的功能函数,

人工智能微客/aiweker 287

python单元测试框架作用_Python自动单元测试框架

简介: 软件的测试是一件非常乏味的事情,在测试别人编写的软件时尤其如此,程序员通常都只对编写代码感兴趣,而不喜欢文档编写和软件测试这类"没有创新"的工作。既然如此,为什么不让程序员在编写软件时自己加入一些用于测试的代码,使测试过程自动化呢?在软件工程中,这一技术称为自动单元测试,本文介绍在用Python开发软件时如何实现这一目标。一、软件测试大型软件系统的开发是一个很复杂的过程,其中因为人的因素而...

weixin_39835607的博客 1024
上一篇: 提升效率的 Pycharm 功能总结
下一篇: 操作系统: 进程和线程
Mleeeeeee
博客等级 码龄10年 65粉丝 57原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值