1. 简介

  上一篇中,我们刚刚实现了在每个用例之前执行初始化操作,那么用例执行完之后如需要清除数据(或还原)操作,可以使用 yield 来实现。fixture通过scope参数控制setup级别,既然有setup作为用例之前前的操作,用例执行完之后那肯定也有teardown操作。
这里用到fixture的teardown操作并不是独立的函数,用yield关键字呼唤teardown操作。fixture的teardown操作并不是独立的函数,可以用yield关键字呼唤teardown操作。 

  我们之前学习的都是测试用例的前置固件,也就是相当于“setup”。说到这,细心的你可能想到了,那有没有什么方式可以表示出“teardown”?这就是我们今天学习的yield和addfinalizer。

yield

  yield是一个关键字,它不是单独存在的,要写在fixtrue标记的固件中。

  我们在声明的固件myfixture中加入yield关键字,在它下面写测试用例执行后想要运行的代码;其他有关于固件的使用没有任何差别。需要说明的一点是我们在pytest主函数中增加了一个参数“–setup-show”,他会显示出固件的执行情况。

  fixture里面的teardown用yield来唤醒teardown的执行

  如果测试用例中的代码出现异常或者断言失败,并不会影响他的固件中yield后的代码执行;但是如果固件中的yield之前的代码也就是相当于setup部分的带代码,出现错误或断言失败,那么yield后的代码将不会再执行,当然测试用例中的代码也不会执行。

  我们也可以通过request.addfinalizer()的方式实现“teardown”

  我们在固件中传入request参数;又在固件中定义了一个内置函数;最后将定义的内置函数添加到request的addfinalizer中

2. scope="function"

当 pytest.fixture(scope="function") 时,pytest的yieId 类似unittest的teartown。每个方法(函数)都会执行一次

1.新建 test_bjhg_function1.py文件,我们看一下是不是这样的。

2.1 代码实现:

2.2 参考代码:

# coding=utf-8
# 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 # 2.注释:包括记录创建时间,创建人,项目名称。
'''
Created on 2020-04-20
@author: 北京-宏哥
Project:《带你装B,带你飞》pytest修仙之路5 - yield操作
'''
# 3.导入模块
import pytest @pytest.fixture(scope="function")
def login():
print("登录成功")
yield
print("用例执行完成,收尾") def test1(login):
print('操作1')
print("-----------------------------------------------") def test2(login):
print('操作2')
print("-----------------------------------------------") def test3(login):
print('操作3')
print("-----------------------------------------------") if __name__ == "__main__":
pytest.main(["-s", "test_bjhg_function1.py"])

2.3 运行结果:

运行代码后,控制台打印如下图的结果

从结果看出,虽然test1,test2,test3三个地方都调用了login函数,并且它会在每一个用例前执行一次

2.如果test1不调用,test2(调用login),test3不调用,运行顺序会是怎样的?

2.4 参考代码:

# coding=utf-8
# 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 # 2.注释:包括记录创建时间,创建人,项目名称。
'''
Created on 2020-04-20
@author: 北京-宏哥
Project:《带你装B,带你飞》pytest修仙之路5 - yield操作
'''
# 3.导入模块
import pytest @pytest.fixture(scope="function")
def login():
print("登录成功")
yield
print("用例执行完成,收尾") def test1():
print('操作1')
print("-----------------------------------------------") def test2(login):
print('操作2')
print("-----------------------------------------------") def test3():
print('操作3')
print("-----------------------------------------------") if __name__ == "__main__":
pytest.main(["-s", "test_bjhg_function1.py"])

2.5 运行结果:

运行代码后,控制台打印如下图的结果

从结果看出,function级别的fixture在当前.py模块里,只会在用例(test_s2)第一次调用前执行一次

3.scope="module"

1.fixture参数scope=”module”,module作用是整个.py文件都会生效( 整个文件只会执行一次),用例调用时,参数写上函数名称就行

3.1 代码实现:

3.2 参考代码:

# coding=utf-8
# 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 # 2.注释:包括记录创建时间,创建人,项目名称。
'''
Created on 2020-04-20
@author: 北京-宏哥
Project:《带你装B,带你飞》pytest修仙之路5 - yield操作
'''
# 3.导入模块
import pytest @pytest.fixture(scope="module")
def login():
print("登录成功")
yield
print("用例执行完成,收尾") def test1(login):
print('操作1')
print("-----------------------------------------------") def test2(login):
print('操作2')
print("-----------------------------------------------") def test3(login):
print('操作3')
print("-----------------------------------------------") if __name__ == "__main__":
pytest.main(["-s", "test_bjhg_function1.py"])

3.3 运行结果:

运行代码后,控制台打印如下图的结果

从结果看出,虽然test1,test2,test3三个地方都调用了login函数,但是它只会在第一个用例前执行一次

2.如果test1不调用,test2(调用login),test3不调用,运行顺序会是怎样的?

3.4 参考代码:

# coding=utf-8
# 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 # 2.注释:包括记录创建时间,创建人,项目名称。
'''
Created on 2020-04-20
@author: 北京-宏哥
Project:《带你装B,带你飞》pytest修仙之路5 - yield操作
'''
# 3.导入模块
import pytest @pytest.fixture(scope="module")
def login():
print("登录成功")
yield
print("用例执行完成,收尾") def test1():
print('操作1')
print("-----------------------------------------------") def test2(login):
print('操作2')
print("-----------------------------------------------") def test3():
print('操作3')
print("-----------------------------------------------") if __name__ == "__main__":
pytest.main(["-s", "test_bjhg_function1.py"])

3.5 运行结果:

运行代码后,控制台打印如下图的结果

从结果看出,module级别的fixture在当前.py模块里,只会在用例(test_s2)第一次调用前执行一次

4. yield执行teardown

  细心的童鞋或者小伙伴可以看到,我前边的代码中有一个yield关键字,大家有点好奇是做什么的,这一小节就给你答疑解惑。其实就是用来唤醒teardown。

1.fixture里面的teardown用yield来唤醒teardown的执行

4.1 代码实现:

4.2 参考代码:

# coding=utf-8
# 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 # 2.注释:包括记录创建时间,创建人,项目名称。
'''
Created on 2020-04-20
@author: 北京-宏哥
Project:《带你装B,带你飞》pytest修仙之路5 - yield操作
'''
# 3.导入模块
import pytest @pytest.fixture(scope="module")
def login():
print("登录成功")
yield
print("执行teardown!")
print("用例执行完成,收尾") def test1(login):
print('操作1')
print("-----------------------------------------------") def test2(login):
print('操作2')
print("-----------------------------------------------") def test3(login):
print('操作3')
print("-----------------------------------------------") if __name__ == "__main__":
pytest.main(["-s", "test_bjhg_function1.py"])

4.3 运行结果:

运行代码后,控制台打印如下图的结果

5. yield遇到异常

1.如果其中一个用例出现异常,不影响yield后面的teardown执行,运行结果互不影响,并且在用例全部执行完之后,会呼唤teardown的内容

5.1 代码实现:

5.2 参考代码:

# coding=utf-8
# 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 # 2.注释:包括记录创建时间,创建人,项目名称。
'''
Created on 2020-04-20
@author: 北京-宏哥
Project:《带你装B,带你飞》pytest修仙之路5 - yield操作
'''
# 3.导入模块
import pytest @pytest.fixture(scope="module")
def login():
print("登录成功")
yield
print("执行teardown!")
print("用例执行完成,收尾") def test1(login):
print('操作1')
print("-----------------------------------------------")
# 如果第一个用例异常了,不影响其他的用例执行
raise NameError # 模拟异常 def test2(login):
print('操作2')
print("-----------------------------------------------") def test3(login):
print('操作3')
print("-----------------------------------------------") if __name__ == "__main__":
pytest.main(["-s", "test_bjhg_function1.py"])

5.3 运行结果:

运行代码后,控制台打印如下图的结果

2.如果在setup就异常了,那么是不会去执行yield后面的teardown内容了

3.yield也可以配合with语句使用,以下是官方文档给的案例

# 官方文档案例
# content of test_yield2.py import smtplib
import pytest @pytest.fixture(scope="module")
def smtp():
with smtplib.SMTP("smtp.gmail.com") as smtp:
yield smtp # provide the fixture value

6.addfinalizer终结函数

1.除了yield可以实现teardown,在request-context对象中注册addfinalizer方法也可以实现终结函数。

# 官方案例

# content of conftest.py
import smtplib
import pytest @pytest.fixture(scope="module")
def smtp_connection(request):
smtp_connection = smtplib.SMTP("smtp.gmail.com", 587, timeout=5)
def fin():
print("teardown smtp_connection")
smtp_connection.close()
request.addfinalizer(fin)
return smtp_connection # provide the fixture value

2.yield和addfinalizer方法都是在测试完成后呼叫相应的代码。但是addfinalizer不同的是:

  • 他可以注册多个终结函数。

  • 这些终结方法总是会被执行,无论在之前的setup code有没有抛出错误。这个方法对于正确关闭所有的fixture创建的资源非常便利,即使其一在创建或获取时失败

7.小结

 好了,今天的分享就到这里吧!!!谢谢各位的耐心阅读。有问题加群交流讨论!!!

您的肯定就是我进步的动力。如果你感觉还不错,就请鼓励一下吧!记得随手点波  推荐  不要忘记哦!!!

别忘了点 推荐 留下您来过的痕迹

参考文档:https://docs.pytest.org/en/latest/

《带你装B,带你飞》pytest修仙之路5 - yield操作的更多相关文章

  1. 《带你装B,带你飞》pytest修仙之路3 - setup/teardown

    1. 简介 学过unittest的都知道里面用前置和后置setup和teardown非常好用,在每次用例开始前和结束后都去执行一次.当然还有更高级一点的setupClass和teardownClass ...

  2. 软件测试工程师人手必备的一只:TOM猫,可以带你装逼带你飞!

    Hi,你来了? 其实没有猫,为了让你们好好学习,天天向上!我可真的是拼了命了! 写这篇文章的缘由是,近期有同学经常问到一个这样的问题: 老师,tomcat是啥? 老师,Linux是啥? 老师,xshe ...

  3. [转载] vim带你装逼带你飞(一)

    前言:逃离windows有很长时间了,特别是当今android盛行的时代,我们没有理由不选择ubuntu作为编译开发android之首选.其实操作系统只是我们使用的一个工具, windows也好lin ...

  4. js一些稀奇古怪的写法-带你装逼带你飞

    //定时器的第三个参数 setInterval(function(str1,str2,num){ alert(str1+str2+num) },1000,'参数1','还可以有很多参数,不同的类型.. ...

  5. vim带你装逼带你飞(一)

    前言:逃离windows有很长时间了,特别是当今android盛行的时代,我们没有理由不选择ubuntu作为编译开发android之首选.其实操作系统只是我们使用的一个工具, windows也好lin ...

  6. vim带你装逼带你飞(二)

    上篇我贴上了我使用的vim配置及插件配置,有这些东西只能是一个脚本堆积,无从谈高效的代码阅读开发. 下面我们就来写经常使用的命令,就从配置F系列快捷键开始吧. F+ n 快捷键配置 F1基本上时帮助, ...

  7. 带你装B,带你飞的大数据时代

    我接触过的大数据有: 1.美国棱镜计划 2.前几天新闻报道的,苹果公司窃取用户隐私 3.百度的用户搜素习惯统计分析 4.淘宝的用户购物习惯分析,智能推荐宝贝 5.浏览器的智能标签页 ... 最想了解的 ...

  8. 《带你装B,带你飞》pytest成魔之路4 - fixture 之大解剖

    1. 简介 fixture是pytest的一个闪光点,pytest要精通怎么能不学习fixture呢?跟着我一起深入学习fixture吧.其实unittest和nose都支持fixture,但是pyt ...

  9. 《带你装B,带你飞》pytest修炼之路1- 简介和环境准备

    1. pytest简介 pytest是python的一种单元测试框架,与python自带的unittest测试框架类似,但是比unittest框架使用起来更简洁,效率更高.根据pytest的官方网站介 ...

随机推荐

  1. 第十五周java实验作业

    实验十五  GUI编程练习与应用程序部署 实验时间 2018-12-6 1.实验目的与要求 (1) 掌握Java应用程序的打包操作: Java程序的打包,程序编译完成后,程序员将.class文件压缩打 ...

  2. 洛谷P1957口算练习题题解

    前言: 题目传送门:https://www.luogu.com.cn/problem/P1957 其实这很简单 纯模拟撒~~~~ 正文开始: _话说 ,就当本蒟蒻正高高兴兴的刷水题时,居然 碰到了这个 ...

  3. 2017-12-08高级.net 面试小结

    现在思维是企业级开发思维 应该往互联网思维转变,主要涉及,队列 ,消息,数据并发,数据安全,前端,vue,element UI 以下为速8酒店笔试题 1.有如下代码: string s1;string ...

  4. Python第六章-函数02-函数的作用域

    函数 三.作用域规则 有了函数之后,我们必须要面对一个作用域的问题. 比如:你现在访问一个变量,那么 python 解析器是怎么查找到这个变量,并读取到这个变量的值的呢? 依靠的就是作用域规则! 3. ...

  5. 【转】.strip().split('t')和.strip().split()

    https://blog.csdn.net/qq_35290785/article/details/94780620 .strip().split('t')line =' nihao, zhenhao ...

  6. effective-java学习笔记---使用接口模拟可扩展的枚举38

    枚举类型( BasicOperation )不可扩展,但接口类型( Operation )是可以扩展的,并且它是用于表示 API 中的操作的接口类型. // Emulated extensible e ...

  7. Nginx Rewrite规则的break和last示例

    break和last各自的作用 官方解释 last:stops processing the current set of ngx_http_rewrite_module directives fol ...

  8. 解析PE文件

    最近在自学解析PE文件,根据小辣椒(CFF Explorer)以及各论坛上大佬的帖子,做了个黑屏打印PE文件的,历时7天完成,在此想跟有相关需要的同学们分享下思路,有不足之处也希望大家不吝赐教,指点出 ...

  9. sql server 数据库安装手册

    1. 双击setup.exe运行安装程序,进入[SQL Server 安装中心] 2. 选择左侧菜单栏[安装],运行第一项[全新安装或向现有安装添加功能] 3. 进入[SQL Server 2008 ...

  10. Python第十一章-常用的核心模块01-collections模块

    python 自称 "Batteries included"(自带电池, 自备干粮?), 就是因为他提供了很多内置的模块, 使用这些模块无需安装和配置即可使用. 本章主要介绍 py ...