python参数化建模 书_Python 中如何实现参数化测试?

之前,我曾转过一个单元测试框架系列的文章,里面介绍了 unittest、nose/nose2 与 pytest 这三个最受人欢迎的 Python 测试框架。

本文想针对测试中一种很常见的测试场景,即参数化测试,继续聊聊关于测试的话题,并尝试将这几个测试框架串联起来,做一个横向的比对,加深理解。

1、什么是参数化测试?

对于普通测试来说,一个测试方法只需要运行一遍,而参数化测试对于一个测试方法,可能需要传入一系列参数,然后进行多次测试。

比如,我们要测试某个系统的登录功能,就可能要分别传入不同的用户名与密码,进行测试:使用包含非法字符的用户名、使用未注册的用户名、使用超长的用户名、使用错误的密码、使用合理的数据等等。

参数化测试是一种“数据驱动测试”(Data-Driven Test),在同一个方法上测试不同的参数,以覆盖所有可能的预期分支的结果。它的测试数据可以与测试行为分离,被放入文件、数据库或者外部介质中,再由测试程序读取。

2、参数化测试的实现思路?

通常而言,一个测试方法就是一个最小的测试单元,其功能应该尽量地原子化和单一化。

先来看看两种实现参数化测试的思路:一种是写一个测试方法,在其内部对所有测试参数进行遍历;另一种是在测试方法之外写遍历参数的逻辑,然后依次调用该测试方法。

这两种思路都能达到测试目的,在简单业务中,没有毛病。然而,实际上它们都只有一个测试单元,在统计测试用例数情况,或者生成测试报告的时候,并不乐观。可扩展性也是个问题。

那么,现有的测试框架是如何解决这个问题的呢?

它们都借助了装饰器,主要的思路是:利用原测试方法(例如 test()),来生成多个新的测试方法(例如 test1()、test2()……),并将参数依次赋值给它们。

由于测试框架们通常把一个测试单元统计为一个“test”,所以这种“由一生多”的思路相比前面的两种思路,在统计测试结果时,就具有很大的优势。

3、参数化测试的使用方法?

Python 标准库中的unittest 自身不支持参数化测试,为了解决这个问题,有人专门开发了两个库:一个是ddt ,一个是parameterized 。

ddt 正好是“Data-Driven Tests”(数据驱动测试)的缩写。典型用法:

import unittest

from ddt import ddt,data,unpack

@ddt

class MyTest(unittest.TestCase):

@data((3, 1), (-1, 0), (1.2, 1.0))

@unpack

def test_values(self, first, second):

self.assertTrue(first > second)

unittest.main(verbosity=2)

运行的结果如下:

test_values_1__3__1_ (__main__.MyTest) ... ok

test_values_2___1__0_ (__main__.MyTest) ... FAIL

test_values_3__1_2__1_0_ (__main__.MyTest) ... ok

==================================================

FAIL: test_values_2___1__0_ (__main__.MyTest)

--------------------------------------------------

Traceback (most recent call last):

File "C:\Python36\lib\site-packages\ddt.py", line 145, in wrapper

return func(self, *args, **kwargs)

File "C:/Users/pythoncat/PycharmProjects/study/testparam.py", line 9, in test_values

self.assertTrue(first > second)

AssertionError: False is not true

----------------------------------------------

Ran 3 tests in 0.001s

FAILED (failures=1)

结果显示有 3 个 tests,并详细展示了运行状态以及断言失败的信息。

需要注意的是,这 3 个 test 分别有一个名字,名字中还携带了其参数的信息,而原来的 test_values 方法则不见了,已经被一拆为三。

在上述例子中,ddt 库使用了三个装饰器(@ddt、@data、@unpack),实在是很丑陋。下面看看相对更好用的 parameterized 库:

import unittest

from parameterized import parameterized

class MyTest(unittest.TestCase):

@parameterized.expand([(3,1), (-1,0), (1.5,1.0)])

def test_values(self, first, second):

self.assertTrue(first > second)

unittest.main(verbosity=2)

测试结果如下:

test_values_0 (__main__.MyTest) ... ok

test_values_1 (__main__.MyTest) ... FAIL

test_values_2 (__main__.MyTest) ... ok

=========================================

FAIL: test_values_1 (__main__.MyTest)

-----------------------------------------

Traceback (most recent call last):

File "C:\Python36\lib\site-packages\parameterized\parameterized.py", line 518, in standalone_func

return func(*(a + p.args), **p.kwargs)

File "C:/Users/pythoncat/PycharmProjects/study/testparam.py", line 7, in test_values

self.assertTrue(first > second)

AssertionError: False is not true

----------------------------------------

Ran 3 tests in 0.000s

FAILED (failures=1)

这个库只用了一个装饰器 @parameterized.expand,写法上可就清爽多了。

同样提醒下,原来的测试方法已经消失了,取而代之的是三个新的测试方法,只是新方法的命名规则与 ddt 的例子不同罢了。

介绍完 unittest,接着看已经死翘翘了的nose 以及新生的nose2 。nose 系框架是带了插件(plugins)的 unittest,以上的用法是相通的。

另外,nose2 中还提供了自带的参数化实现:

import unittest

from nose2.tools import params

@params(1, 2, 3)

def test_nums(num):

assert num < 4

class Test(unittest.TestCase):

@params((1, 2), (2, 3), (4, 5))

def test_less_than(self, a, b):

assert a < b

最后,再来看下 pytest 框架,它这样实现参数化测试:

import pytest

@pytest.mark.parametrize("first,second", [(3,1), (-1,0), (1.5,1.0)])

def test_values(first, second):

assert(first > second)

测试结果如下:

==================== test session starts ====================

platform win32 -- Python 3.6.1, pytest-5.3.1, py-1.8.0, pluggy-0.13.1

rootdir: C:\Users\pythoncat\PycharmProjects\study collected 3 items

testparam.py .F

testparam.py:3 (test_values[-1-0])

first = -1, second = 0

@pytest.mark.parametrize("first,second", [(3,1), (-1,0), (1.5,1.0)])

def test_values(first, second):

> assert(first > second)

E assert -1 > 0

testparam.py:6: AssertionError

. [100%]

========================= FAILURES ==========================

_________________________ test_values[-1-0] _________________________

first = -1, second = 0

@pytest.mark.parametrize("first,second", [(3,1), (-1,0), (1.5,1.0)])

def test_values(first, second):

> assert(first > second)

E assert -1 > 0

testparam.py:6: AssertionError

===================== 1 failed, 2 passed in 0.08s =====================

Process finished with exit code 0

依然要提醒大伙注意,pytest 也做到了由一变三,然而我们却看不到有新命名的方法的信息。这是否意味着它并没有产生新的测试方法呢?或者仅仅是把新方法的信息隐藏起来了?

4、最后小结

上文中介绍了参数化测试的概念、实现思路,以及在三个主流的 Python 测试框架中的使用方法。我只用了最简单的例子,为的是快速科普(言多必失)。

但是,这个话题其实还没有结束。对于我们提到的几个能实现参数化的库,抛去写法上大同小异的区别,它们在具体代码层面上,又会有什么样的差异呢?

具体来说,它们是如何做到把一个方法变成多个方法,并且将每个方法与相应的参数绑定起来的呢?在实现中,需要解决哪些棘手的问题?

在分析一些源码的时候,我发现这个话题还挺有意思,所以准备另外写一篇文章。那么,本文就到此为止了,谢谢阅读。

0daedc8ec42a6a3b3e0c60348ddf2326.png

公众号【Python猫】, 本号连载优质的系列文章,有喵星哲学猫系列、Python进阶系列、好书推荐系列、技术写作、优质英文推荐与翻译等等,欢迎关注哦。

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

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

相关文章

反模式设计_设计模式:模式或反模式,这就是问题

反模式设计我最近遇到了Wiki页面“ Anti-pattern” &#xff0c;其中包含详尽的反模式列表。 其中一些对我来说很明显。 他们中的一些让我想了一下&#xff0c;其他的让我想了更多。 然后&#xff0c;我开始在页面上查找反模式“ singleton”&#xff0c;但找不到。 &#xff0…

光端机的几种物理接口类型

光端机&#xff0c;就是光信号传输的终端设备。光端机现在能传输的业务很多&#xff0c;如&#xff1a;视频&#xff0c;音频&#xff0c;数据&#xff0c;开关量&#xff0c;电话&#xff0c;以太网等。那么&#xff0c;你对光端机的几种物理接口了解吗&#xff0c;是否懂得光…

js中的数据类型分为两大类分别是什么_数据类型有这么重要吗?

一个没有得到重视的知识点, 数据类型 每种语言都有自己的数据类型,下面以javascript为例 类型的分类 js的数据类型可以分为 两大类: 1,值类型 (String,Number,undefined,Boolean,null) 2,引入类型(Object,Function,Array) 个人理解也可以把值类型和引入类型分为简单类型和复杂类…

监控系统几种常见的光端机传输方案拓扑图

近几年随着模拟摄像机被网络摄像机以及高清同轴摄像机取代&#xff0c;在光纤传输层&#xff0c;之前使用量比较大的视频光端机也逐渐被光纤收发器、POE交换机、网络交换机等网络光通信设备取代掉。目前市场上音频、数据、开关量、电话、对讲等信号依然可以通过光端机来进行传输…

在等待Jakarta EE时

自甲骨文在JavaOne 2017宣布将Java™EE转移到Eclipse Foundation以来已有一年多了。此后发生了很多事情&#xff1a; Java™EE 8 API和实现项目已在EE4J下建立 。 Eclipse GlassFish 5.1 版本即将发布 。 全新的Jakarta EE规范流程指日可待。 社区显示出有关Jakarta EE技术…

[渝粤教育] 中国地质大学 信息检索 复习题 (2)

信息检索-模拟题 一.选择题 1.在CNKI中以下哪一个对检索结果的排序能够体现最新的文献 A.按照主题排序 B.按照下载量排 C.按照被引量排序 D.按照发表时间排序(降序) 2.ISBN是什么的缩写? A.国际标准刊号 B.国际标准书号 C.连续出版物代码 D.国内统一刊号 3.一篇论文列出的参…

[渝粤教育] 中国地质大学 劳动与社会保障法 复习题

《劳动与社会保障法》模拟题 一单选题 1.对劳动合同的无效或者部分无效有争议的由()或者人民法院确认. A.劳动行政部门 B.劳动监察机构 C.劳动争议调解委员会 D.劳动争议仲裁机构 2.用人单位经济性裁员时应当优先留用(). A.订立固定期限劳动合同的人员 B.订立无固定期限劳动合…

mysql导出包_mysql导入导出包括函数或者存储过程

mysql导入导出包括函数或者存储过程1.mysql导出整个数据库mysqldump -h hostname -u username -p databasename > backupfile.sql如果root用户没用密码可以不写-p&#xff0c;当然导出的sql文件你可以制定一个路径&#xff0c;未指定则存放在mysql的bin目录下 www.2cto.co…

[渝粤教育] 中国地质大学 城镇规划 复习题 (2)

《城市规划》模拟题 一.单选题 1.城镇规划所需编制的文件按原国家建委1980年颁布的《城市规划编制审批暂行办法》规定分为(). A.规划图纸和说明书 B.规划文件和说明书 C.城镇现状图和说明书 D.规划说明书和城镇现状图 2.城镇是区域生产力结集中心首先是()的中心. A.区域农业生…

[渝粤教育] 中国地质大学 大学语文 复习题 (2)

《大学语文》模拟题 一.单选题 1.李商隐《无题》中借神化传说抒情的诗句是() A.相见时难别亦难东风无力百花残 B.春蚕到死丝方尽蜡炬成灰泪始干 C.晓镜但愁云鬓改夜吟应觉月光寒 D.蓬山此去无多路青鸟殷勤为探看 2.戴望舒《我用我残陨的手掌》中“只有那辽远的一角依然完整”…

如何验证python的下载安装_如何下载python并正确安装

我最近在学数据分析入门课&#xff0c;这个老师讲的比较适合零基础的,也是用WINDOWS做演示&#xff0c;还PUSH了很多代码资料&#xff0c;我发你看看有没有帮助哈安装miniconda下载python3的64-bit版本即可。注意&#xff0c;一定要64位的版本。(这里选择3.6或者2.7没关系&…

工业交换机外壳选用时有什么要求?

我们一般在选择工业交换机时&#xff0c;更多的是关注工业交换机的温度范围、EMC电磁兼容性、安装方式和电源等&#xff0c;而对于工业交换机的外壳关注比较少&#xff0c;除了一些客户需要防水要求的。接下来就由飞畅科技的小编来为大家介绍一下工业交换机外壳选用有什么要求?…

基于drools_Drools:基于PHREAK堆栈的评估和向后链接

基于drools前一段时间&#xff0c;我写了一篇有关我们新算法的博客&#xff1a; http : //blog.athico.com/2013/11/rip-rete-time-to-get-phreaky.html 有人问我有关新的基于堆栈的系统以及向后链接如何工作的信息。 我在电子邮件中回复了他们&#xff0c;但我认为其他人可能…

[渝粤教育] 中国地质大学 微积分(一) 复习题 (2)

《微积分(一)》模拟题 一.单选题 1.求极限-) A.-1 B.0 C.1 D.∞ 2.求极限 A.0 B.1 C.1/2 D.3/2 3.设函数在内连续求的值. A.5 B.6 .7 D.8 4.求函数当1时的增量. A.0.1 B.0.2 C.0.3 D.0.4 5.求极限 A.1 B.1/2 C.1/3 D.1/4 6.求极限 A.-1 B.0 C.1 D.2 7.求极限 A.1 B.2 C…

[渝粤教育] 中国地质大学 政府与事业单位会计 复习题

《政府与事业单位会计》模拟题 一.单选题 1.校办工厂将纯收入的一部分上缴学校学校应记作(). A.经营收入 B.事业收入 C.附属单位上缴收入 D.其他收入 2.事业单位的任务不包括() A.组织资金供应合理使用资金 B.保护公共财产合理分配结余 C.积极开辟财源实行盈亏核算 D.反映预…

mysql内表和外表_Hive内表和外表的区别

本文以例子的形式介绍一下Hive内表和外表的区别。例子共有4个&#xff1a;不带分区的内表、带分区的内表、不带分区的外表、带分区的外表。1 不带分区的内表#创建表create table innerTable(id int,name string) row format delimited fields terminated by ‘|’;(show tables…

工业交换机与光纤收发器的区别

工业交换机与光纤收发器效果有什么差异工业交换机与光纤收发器不同的是&#xff0c;光纤收发器其实是点对点的工业工业交换机&#xff0c;光纤收发器只是一种光电转化设备&#xff0c;仅仅只是用于因传输间隔过远而采取的一种延长传输间隔的一种手法&#xff1b;而工业交换机是…

使用React Native和Spring Boot构建一个移动应用

“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕&#xff1f; 尝试使用Okta API进行托管身份验证&#xff0c;授权和多因素身份验证。 React Native是使用React构建移动应用程序的框架。 React允许您使用声明式编程风格来…

[渝粤教育] 中国地质大学 概率论与数理统计 复习题 (2)

《概率论与数理统计》模拟题 一.单选题 1.对于事件AB下列命题正确的是(). A.若AB互不相容则与也互不相容. B.若AB相容那么与也相容. C.若AB互不相容且概率都大于零则AB也相互独立. D.若AB相互独立那么与也相互独立. 2.在一次假设检验中下列说法正确的是(). A.既可能犯第一类错…

mysql 操作指令详解_Mysql常用命令详解

Mysql安装目录数据库目录/var/lib/mysql/配置文件/usr/share/mysql(mysql.server命令及配置文件)相关命令/usr/bin(mysqladmin mysqldump等命令)启动脚本/etc/init.d/mysql(启动脚本文件mysql的目录)系统管理连接MySQL格式: mysql -h 主机地址 -u用户名 -p用户密码例 1:连接到本…