【Python】Python代码的单元测试

Python代码的单元测试

单元测试的概念

  • 定义:是指对软件中的最小可测试单元进行检查和验证。

  • 作用:可以确保程序模块是否否和我们规范的输出,保证该模块经过修改后仍然是满足我们的需求。

单元测试的策略

如果要创建单元测试,可以遵循如下基本技巧来确保涵盖所有的测试用例。

  • 逻辑检查:给定正确的、符合预期的输入,系统是否能够执行正确的计算并遵循通过代码正确的路径?给定的输入是否涵盖通过代码的所有路径?

  • 边界检查:对于给定的输入,系统如何响应? 系统如何响应典型输入、边缘用例或无效输入?假设您期望输入的整数介于 3 和 7 之间。当您使用 5(典型输入)、3(边缘用例)或 9(无效输入)时,系统会如何响应?

  • 错误处理:当输入中出现错误时,系统会如何响应? 是否提示用户输入其他内容? 软件是否会崩溃?

  • 面向对象的检查:如果通过运行代码更改任何持久对象的状态,则该对象是否正确更新?

单元测试类的编写

  1. 首先编写要进行单元测试的代码。

    def add(x, y):"""加法函数"""return x + ydef subtract(x, y):"""减法函数"""return x - ydef multiply(x, y):"""乘法函数"""return x * ydef divide(x, y):"""除法函数"""if y != 0:return x / yelse:return ValueError("除数不能为0")
  2. 编写测试工具代码。

    # 测试代码应使用test_xxx的名称进行规范
    # 这里使用断言assert进行模拟
    # assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常
    # 如下代码执行正常不报错,则说明函数执行符合预期
    from myfunctions import divide# 一个简单的单元测试示例
    def test_divide(x, y, result):r = divide(x, y)assert result == rdef test_divide_error(x, y):try:divide(x, y)except ValueError:assert False
  3. 执行单元测试的工具代码。

    单元测试执行完成,无错误输出代码执行符合预期。

Python中的单元测试类

如上的代码能够满足Python中进行单元测试的需求,但如果换一套方法,我们的单元测试又需要手动编码,Python中提供了专业的单元测试工具类:unittest,以下是该单元测试类的使用方法介绍。

unittest 将我们常规用到的测试场景封装了以下断言方法,根据测试所需要的场景进行引用。

断言方法方法解释
assertEqual(a, b)检查a 和b 是否相等。
assertNotEqual(a, b)检查a 和b 是否不相等。
assertTrue(x)检查x 是否为True。
assertFalse(x)检查x 是否为False。
assertIs(a, b)检查a 和b 是否为同一对象(is)。
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 类型的实例。
assertAlmostEqual(a, b)检查a 和b 是否近似相等(适用于浮点数比较)。
assertNotAlmostEqual(a, b)检查a 和b 是否不近似相等(适用于浮点数比较)。
assertRaises(Error, func, *args, **kwargs)检查当调用function 时是否抛出了Error 异常。

unittest模块的基础使用

单元测试代码:

# unittest 是python自带的工具包,无需单独下载
import unittest
from myfunctions import *class TestMyFunctions(unittest.TestCase):def test_add(self):# assertEqual,断言测试方法,`unittest` 将我们常规用到的测试场景封装成断言方法,根据测试所需要的场景进行引用。self.assertEqual(add(1, 2), 3)self.assertEqual(add(-1, 2), 1)self.assertEqual(add(-1, -2), -3)def test_subtract(self):self.assertEqual(subtract(1, 2), -1)self.assertEqual(subtract(-1, 2), -3)self.assertEqual(subtract(-1, -2), 1)def test_multiply(self):self.assertEqual(multiply(1, 2), 2)self.assertEqual(multiply(-1, 2), -2)self.assertEqual(multiply(-1, -2), 2)def test_divide(self):self.assertEqual(divide(1, 2), 0.5)self.assertEqual(divide(-1, 2), -0.5)self.assertEqual(divide(-1, -2), 0.5)

unittest 代码并不能够直接运行,有以下执行方法:

  • 命令行:

    python -m unittest test_myfunctions.py

    注意:这里的启动如果写成 python.exe -m unittest .\test_myfunctions.py 会报如下错误。

  • main 函数:

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

unittest模块的前置方法

在实际的测试中可能同时存在多个前置相同的测试,unittest模块提供了setUp()用于在测试开始前执行相关环境的设置,tearDown()setUp() 方法之后进行执行。

注:这里的 setUp 和 tearDown 是固定的函数名,不允许更改。

要测试的代码:

def divide(x, y):"""除法函数"""print("divide called")if y != 0:return x / yelse:raise ValueError("除数不能为0")

测试工具类:

import unittest
from myfunctions import *class TestMyFunctions(unittest.TestCase):def setUp(self):self.test_value_a = 10self.test_value_b = 5self.test_value_c = 0print("setUp called")def tearDown(self):del self.test_value_adel self.test_value_bdel self.test_value_cprint("tearDown called")def test_divide(self):self.assertEqual(divide(self.test_value_a, self.test_value_b), 2)self.assertRaises(ValueError, divide, self.test_value_a, self.test_value_c)if __name__ == '__main__':unittest.main()

代码执行测试:

可以看到,在执行函数测试之前,首先调用了 setUp() 前置方法,然后执行测试,测试结束后,调用 tearDown() 清理单元测试。

测试覆盖率

覆盖率是用来度量测试完整性的手段,是测试效果衡量的标准,是测试技术有效性的度量: 覆盖率 = (至少被执行一次的项目(item)数) / (项目的总数)

Python中提供了测试覆盖率的模块类:coverage,该第三方包需要手动安装。

这里使用如下方法直接进行代码的测试覆盖率分析

# 调用单元测试工具类
coverage run -m unittest discover
# 输出测试报告
coverage report

这里的代码测试覆盖率较低,对单元测试工具类进行优化,要测试的代码如下:

def add(x, y):"""加法函数"""return x + ydef subtract(x, y):"""减法函数"""return x - ydef multiply(x, y):"""乘法函数"""return x * ydef divide(x, y):"""除法函数"""print("divide called")if y != 0:return x / yelse:raise ValueError("除数不能为0")

优化后的单元测试方法为:

import unittest
from myfunctions import *class TestMyFunctions(unittest.TestCase):def setUp(self):self.test_value_a = 10self.test_value_b = 5self.test_value_c = 0print("setUp called")def tearDown(self):del self.test_value_adel self.test_value_bdel self.test_value_cprint("tearDown called")def test_add(self):self.assertEqual(add(self.test_value_a, self.test_value_b), 15)self.assertEqual(add(self.test_value_a, self.test_value_c), 10)def test_subtract(self):self.assertEqual(subtract(self.test_value_a, self.test_value_b), 5)self.assertEqual(subtract(self.test_value_a, self.test_value_c), 10)def test_multiply(self):self.assertEqual(multiply(self.test_value_a, self.test_value_b), 50)self.assertEqual(multiply(self.test_value_a, self.test_value_c), 0)def test_divide(self):self.assertEqual(divide(self.test_value_a, self.test_value_b), 2)self.assertRaises(ValueError, divide, self.test_value_a, self.test_value_c)if __name__ == '__main__':unittest.main()

结果测试

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

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

相关文章

java SSM新闻管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM新闻管理系统是一套完善的web设计系统(系统采用SSM框架进行设计开发,springspringMVCmybatis),对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S…

Map和Set(哈希表)

目录 map: map说明: Map.Entry的说明:,v> Map 的常用方法: 演示: 注意: TreeMap和HashMap的区别 Set: 常见方法说明: 注意: TreeSet和HashSet的区别 哈希表: 冲突&a…

使用LORA微调RoBERTa

模型微调是指在一个已经训练好的模型的基础上,针对特定任务或者特定数据集进行再次训练以提高性能的过程。微调可以在使其适应特定任务时产生显着的结果。 RoBERTa(Robustly optimized BERT approach)是由Facebook AI提出的一种基于Transfor…

【王道数据结构】【chapter5树与二叉树】【P158t8】

设树B是一颗采用链式结构存储的二叉树&#xff0c;编写一个把树B种所有节点的左、右子树进行交换的函数。 #include <iostream> #include <stack> typedef struct treenode{char data;struct treenode *left;struct treenode *right; }treenode,*ptreenode;ptreeno…

docker磁盘不足!已解决~

目录 &#x1f35f;1.查看docker镜像目录 &#x1f9c2;2.停止docker服务 &#x1f953;3.创建新的目录 &#x1f32d;4.迁移目录 &#x1f37f;5.编辑迁移的目录 &#x1f95e;6.重新加载docker &#x1f354;7.检擦docker新目录 &#x1f373;8.删掉旧目录 1.查看doc…

Linux系统之部署File Browser文件管理系统

Linux系统之部署File Browser文件管理系统 一、File Browser介绍1.1 File Browser简介1.2 File Browser功能1.3 File Browser使用场景 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、检查本地环境3.1 检查本地操作系统版本3.2 检查系统内核版本 四、安装File Browser4…

11-OpenFeign-实现负载均衡策略

2021.0.1版本使用 spring-cloud-loadbalancer 1、默认开启负载均衡策略 使用default RoundRobinLoadBalancer策略 无需yaml文件配置&#xff0c;openfeignclient配置 RandomLoadBalancer &#xff1a;基于随机访问的负载均衡策略NacosLoadBalancer&#xff1a;基于Nacos权重…

Java:什么是向上转型与向下转型(详细图解)

目录 一、什么是向上转型 1、概念 2、代码示例 3、向上转型的优缺点 二、什么是向下转型 1、向下转型的概念 ​编辑 2、代码示例 三、向下转型的缺点及 instanceof 的使用 1、向下转型的缺点 2、instanceof的使用 一、什么是向上转型 1、概念 向上转型就是创建一个…

【MySQL进阶之路】通过实操理解 explain 执行计划

欢迎关注公众号&#xff08;通过文章导读关注&#xff1a;【11来了】&#xff09;&#xff0c;及时收到 AI 前沿项目工具及新技术的推送&#xff01; 在我后台回复 「资料」 可领取编程高频电子书&#xff01; 在我后台回复「面试」可领取硬核面试笔记&#xff01; 文章导读地址…

重复导航到当前位置引起的。Vue Router 提供了一种机制,阻止重复导航到相同的路由路径。

代码&#xff1a; <!-- 侧边栏 --><el-col :span"12" :style"{ width: 200px }"><el-menu default-active"first" class"el-menu-vertical-demo" select"handleMenuSelect"><el-menu-item index"…

Python算法题集_LRU 缓存

Python算法题集_LRU 缓存 题146&#xff1a;LRU 缓存1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【队列字典】2) 改进版一【有序字典】3) 改进版二【双向链表字典】 4. 最优算法 本文为Python算法题集之一的代码示例 题146&#xff1a;LRU …

Java面试、进阶、实践一网打尽(由电子工业出版社出版)

Java面试、进阶、实践一网打尽 准备好应对Java开发的新挑战吗&#xff1f;我们为您精选了五本核心书籍&#xff0c;一站式满足您在Java面试准备、技能进阶和实战应用的需求。 这套书籍包括《Offer来了&#xff1a;Java面试核心知识点精讲&#xff08;第2版&#xff09;》、《…