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…

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技术…

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

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

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

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

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

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

交换机的特点及工作原理

交换机有多个端口&#xff0c;每个端口都具有桥接功能&#xff0c;可以连接一个局域网或一台高性能服务器或工作站&#xff0c;实际上&#xff0c;交换机有时被称为多端口网桥。那么&#xff0c;对于交换机的特点以及工作原理这块你是否有了解呢&#xff1f;接下来我们就来为大…

Spark UI的见解

作为延续解剖的-Apache的火花的工作后&#xff0c;我将分享如何利用星火UI调谐工作。 我将继续使用先前文章中使用的相同示例&#xff0c;新的spark应用程序将在以下方面完成工作 –阅读纽约市停车票 –通过“板ID”进行汇总并计算违规日期 –保存结果 此代码的DAG看起来像…

光纤收发器的6个指示灯说明

我们常用的光纤收发器都有6个指示灯&#xff0c;那么每个指示灯都代表什么含义呢&#xff1f;是否所有指示灯都亮起才代表光纤收发器正常工作呢&#xff1f;接下来飞畅科技的小编就来为大家详细说明一下&#xff0c;一起来看看吧&#xff01; 光纤收发器的指示灯说明&#xff…

如何通过光纤收发器指示灯来判断收发器的故障

我们常用的光纤收发器都有6个LED指示灯&#xff0c;它们显示了收发器的工作状态&#xff0c;根据LED所示&#xff0c;就能判断出收发器是否工作正常和可能有什么问题&#xff0c;从而能帮助找出故障。那么&#xff0c;光纤收发器的每个指示灯都有什么含义呢&#xff1f;是否所有…

单纤光纤收发器a与b怎么放?如何使用光纤收发器的AB端?

光纤收发器的ab端是发射端&#xff08;a端&#xff09;和接收端&#xff08;b端&#xff09;&#xff0c;单纤收发器两端分别是A端与B端&#xff0c;这两端的波长不同&#xff0c;发射端的波长比接收端的波长短&#xff0c;而双纤收发器其实是不分AB端的&#xff0c;因为它两端…

您的API是什么情况?

免责声明&#xff1a;在纯REST中&#xff0c;API是不透明的&#xff0c;URL应该是在对先前请求的响应中作为链接发送的内容。 但是&#xff0c;我不是在讲纯REST&#xff0c;而是在讲更实用的API&#xff0c;其中涉及REST的一些概念以及通用的API最佳实践。 编写API时&#xf…

家用光纤猫设备、光纤收发器和光电交换机介绍

光纤能转换网线吗&#xff1f;光纤是一种光导玻璃纤维&#xff0c;传输的是光信号&#xff0c;是不能直接与网线连接&#xff0c;需要通过光电转换设备&#xff0c;将光信号转换成网络信号&#xff0c;常见的光电转换设备有家用光纤猫设备、光纤收发器和光电交换机。接下来就由…

浅谈模拟光端机和数字光端机的区别?

光纤和光端机应用在监控领域里主要是为了解决两个问题&#xff1a;一是传输距离&#xff0c;一是环境干扰。双绞线和同轴电缆只能解决短距离、小范围内的监控图象传输问题&#xff0c;如果需要传输数公里甚至上百公里距离的图象信号则需要采用光纤传输方式。光端机为监控系统提…

Java io字符流读入英文_Java IO 系列教程(四)-字符输入流(2)

本文介绍字符输入流在前面一节中&#xff0c;我们向一个文件中写入了一些字符&#xff0c;通过图片可以看出总共是6个中文字符和一个换行&#xff0c;总共是20个字节&#xff0c;可以推算出字符编码是utf-8&#xff0c;每个汉子占3三个字节。本文就用字符输入流来读一下。代码部…

AWS上的应用程序自动扩展–选项及其对性能的影响

扩展软件应用程序是至关重要的&#xff0c;以避免由于网站的客户群或需要处理大量数据集的应用程序等增加而导致工作负载增加的性能瓶颈。云服务提供商通常是访问其他应用程序的最佳方法随需应变的资源&#xff0c;可根据应用程序的负载变化来扩大或缩小。 1.什么是可伸缩性&a…

模拟光端机和数字光端机的优缺点介绍

视频光端机在中国的发展是伴随着监控发展开始的&#xff0c;常用的视频监控光端机在技术实现上分为模拟调制的光端机和数字非压缩编码光端机两大类。由于在对外接口上都是标准的基带视频接口&#xff0c;单从外观上是很难区分模拟光端机和数字光端机。那么&#xff0c;模拟光端…

什么是DVI光端机?dvi光端机的优势有哪些?

DVI光端机是由DVI发送器&#xff08;DVI-T&#xff09;和DVI接收器&#xff08;DVI-R&#xff09;组成&#xff0c;通过一芯单模光纤传输DVI、VGA、Audip、RS232信号。接下来我们就来为大家详细介绍下什么是DVI光端机&#xff1f;感兴趣的朋友就一起来详细了解下吧&#xff01;…

mysql技术大会2020_2020年数据库技术大会助力技术提升

下半年的技术大会比较多&#xff0c;作为数据库技术从业人员&#xff0c;自然比较关注数据库技术大会&#xff0c;有幸参加过几次数据技术嘉年华&#xff0c;每次参会能遇到很多数据库领域的知名专家&#xff0c;认真聆听技术大咖的主题分享总能获得很多数据库发展动态和技术知…