千锋教育-做有情怀、有良心、有品质的职业教育机构

400-811-9990
手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

上海
  • 北京
  • 郑州
  • 武汉
  • 成都
  • 西安
  • 沈阳
  • 广州
  • 南京
  • 深圳
  • 大连
  • 青岛
  • 杭州
  • 重庆
当前位置:西安千锋IT培训  >  技术干货  >  Python使用装饰器在执行单元测试时配置环境

Python使用装饰器在执行单元测试时配置环境

来源:千锋教育
发布人:xqq
时间: 2023-11-06 11:41:37

装饰器的定义是给一个对象动态加载功能,就像打游戏时给队友上buff一样。一直以来,我对装饰器用的不多,经常会用别的方式搞定,虽然代码丑一点,但也能用。这次遇到一个特别适合装饰器的应用场景,就是执行单元测试时的环境配置。

我是用pytest做单元测试,测试入口都是一个个test_打头的函数。和unittest不一样,pytest中并没有setUp这个方法,虽然有fixture,但读人家的源码时也很少看到有人用,这次遇到问题发现,我靠,就是加个装饰器的事,可以把setUp和tearDown一起做了,何必多此一举。

应用场景用个demo举例,由于生产环境和测试环境的不同,在测试环境中初始化Demo会报错,比如下面这个模块。

importsys

classDemo():

def__init__(self):

fail()

deffail():

ifsys.argv[0].split('\\')[-1].find('test')>-1:

raiseEnvironmentError(__name__)

defsuccess():

print(__name__)

定义了一个Demo类,初始化时会调用fail函数,这个函数在pytest环境下使用时会raise一个EnvironmentError。解决方案就是在这个Demo被调用时将模块中的fail函数替换为success函数。两个单元测试用例如下。

importdemo

deftest_demo():

try:

demo.Demo()

exceptExceptionase:

assertisinstance(e,EnvironmentError)

@replace#替换环境的装饰器

deftest_replace_demo():

demo.Demo()

其中,replace就是替换环境用的装饰器。装饰器代码如下。

defreplace(fun):#定义装饰器,传入函数名

_=demo.fail#保存模块中的fail,以便后面恢复

demo.fail=demo.success#更改

definner():#闭包函数

fun()

demo.fail=_#恢复模块中fail函数

returninner()

用装饰器配置单元测试环境真是优雅无比,写完后顿时腰不酸背不痛了呢。。。

装饰器的难点之一就是闭包(closure),闭包这个翻译在中文里没有很形象的对应关系,这造成了理解障碍。这种例子挺多的,就像单例模式最广泛的用途并不是提供一个的“单例”,叫“超级全局宇宙唯一变量”比较好。协程的功能里一点‘协’的作用都没有,叫“想在什么时候挂起就在什么适合挂起程”比较好。这样一想,闭包是不是叫“跨作用域包”或“脚踏两条船包”或“闭合环境打包”比较好。

闭包的一个定义是这样的:

Closuresarefunctionsthatrefertoindependent(free)variables(variablesthatareusedlocally,butdefinedinanenclosingscope).Inotherwords,thesefunctions'remember'theenvironmentinwhichtheywerecreated.

闭包的关键能力之一是获取上级作用域,另一个关键点在于python中函数是一个对象,可以传来传去,比如作为返回值。这两点结合起来就可以将函数所处的环境打包传到目标区域。在上面一个例子中inner就是一个闭包函数,它在这里的作用就是将inner函数之前的那个区域,就是第二行和第三行。

下面还有个闭包的例子,可以看到在inner外定义了a,b,在inner中使用了a,在test_closure函数实例化后可以看看其__closure__方法中的对象,这个__closure__只包含了a,并没包含b,因为b没有在inner中使用,被垃圾回收了,而a保留了下来,而a就是由于闭包的特性保留下来的,可以用pdb来看看__closure__中是否保留了b。

deftest_closure():

a,b=1,2

definner():

print(a)

returninner

close=test_closure()

print(close.__closure__[0])#

另外,python中的闭包和javascript中的闭包是一个意思,可能需要实现的功能没js中那么多,但理解python闭包时可以参考js的教程。

以上内容为大家介绍了Python使用装饰器在执行单元测试时配置环境,希望对大家有所帮助,如果想要了解更多Python相关知识,请关注IT培训机构:千锋教育。

声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。

猜你喜欢LIKE

怎么更改python的编码

2023-11-06

python怎样将两个list合并

2023-11-06

python如何输出不回车换行

2023-11-06

最新文章NEW

Python脚本如何使用

2023-11-06

Python中apscheduler执行使用步骤

2023-11-06

python 插入排序

2023-11-06

相关推荐HOT

更多>>

快速通道 更多>>

最新开班信息 更多>>

网友热搜 更多>>