python学习-pytest-fixture

Posted 给自己一个向前进的理由

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python学习-pytest-fixture相关的知识,希望对你有一定的参考价值。

一、fixture优势
1、fixture相对于setup和teardown来说应该有以下几点优势:
命名方式灵活,不局限于setup和teardown这几个命名
conftest.py配置里可以实现数据共享,不需要import就能自动找到一些配置
scope="module"可以实现多个.py跨文件共享前置
scope="session"以实现多个.py跨文件使用一个session来完成多个用例
2、使用装饰器标记fixture的功能
fixture(scope="function",params=None,autouse=False,ids=None,name=None)

可以使用此装饰器(带或不带参数)来定义fixture功能。fixture功能的名称可以在以后使用,引用它会在运行测试之前调用它:

test模块或类可以使用pytest.mark.usefixtures(fixturename)标记
测试功能可以直接使用fixture名称作为输入参数,在这种情况下,夹具实例从fixture返回功能将被注入
二、fixture参数介绍
fixture(scope="function",params=None,autouse=False,ids=None,name=None)

1、scope

scope参数有四个级别参数:"function"(默认)、"class"、"module"、"session"

2、params

一个可选的参数列表,它将导致多个参数调用fixture功能和所有测试使用它

3、autouse

如果为True,则为所有测试激活fixture func 可以看到它

如果为False(默认值),则显式需要参考来激活fixture

4、ids

每个字符串id的列表,每个字符串对应于params,这样他们就是测试ID的一部分,如果没有提供ID它们将从params自动生成

5、name

fixture的名称,这默认为装饰函数的名称。如果fixture在定义它的同一模块中使用,夹具的功能名称将被请求夹具的功能arg遮蔽;解决这个问题的一种方法是将装饰函数命名"fixture_<fixturename>",然后使用"@pytest.fixture(name=\'<fixturename>\')"

备注:fixtures可以选择使用yield语句为测试函数提供它们的值,而不是return。在这种情况下,yield语句之后的代码块作为拆卸代码执行,而不管测试结果如何。fixture功能必须只产生一次

三、fixture参数传入(scope="function")
1、实现场景:用例1需要先登录,用例2不需要登录,用例3需要先登录

#!encoding=utf-8
import pytest
 
#不带参数时默认scope="function"
@pytest.fixture()
def login():
    print("输入账号,密码先登录")
 
def test_s1(login):
    print(\'用例1:登录之后其他动作111\')
 
def test_s2():  #不传login
    print(\'用例2:不需要登录,操作222\')
 
def test_s3(login):
    print(\'用例3:登录之后其他动作333\')
 
if __name__=="__main__":
    pytest.main(\'-s test_class004.py\')

运行结果:

 

 

 

2、如果@pytest.fixture()里面没有参数,那么默认scope="function",也就是此时的级别的function,针对函数有效

3、在test用例当中加入了login参数之后,那么在运行用例之前会先运行fixture装饰器内的函数login

四、fixture参数传入(scope="module")
1、fixture参数scope="module",module作用是整个.py文件都会生效,用例调用时,参数写上函数名称就行

#!encoding=utf-8
import pytest
 
@pytest.fixture(scope="module")
def open():
    print("打开浏览器,并且打开百度首页")
 
def test_s1(open):
    print("执行用例1")
 
def test_s2(open):
    print("执行用例2")
 
def test_s3(open):
    print("执行用例3")
 
if __name__=="__main__":
    pytest.main(\'-s test_class005.py\')

运行结果:

 

 

 

从结果看出,虽然test_s1、test_s2、test_s3三个地方调用了open函数,但是它只会在第一个用例执行前执行一次

2、如果test_s1不调用,test_s2调用open函数,test_s3不调用,运行顺序会怎么样?

#!encoding=utf-8
import pytest
 
@pytest.fixture(scope="module")
def open():
    print("打开浏览器,并且打开百度首页")
 
def test_s1():
    print("执行用例1")
 
def test_s2(open):
    print("执行用例2")
 
def test_s3():
    print("执行用例3")
 
if __name__=="__main__":
    pytest.main(\'-s test_class005.py\')

运行结果:

 

 

 

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

五、conftest.py配置
1、上面的案例是在同一个.py文件中,多个用例调用一个登录功能,如果有多个.py的文件都需要调用这个登陆功能的话,那就不能把登陆写到用例里面去,此时应该要有一个配置文件,单独管理一些预置的操作场景,pytest里面默认读取conftest.py里面的配置

conftest.py配置需要注意以下几点:

conftest.py配置脚本名称是固定的,不能修改名称
conftest.py与运行的用例要在同一个package下,并且有init.py文件(亲测conftest.py只要在运行用例文件的上级目录或者在同一个package都可以被调用到,不一定非要在同一个package当中,可以调整conftest.py的位置进行测试)
不需要import导入conftest.py,pytest用例会自动查找

 

 

 

#conftest.py
 
#!encoding=utf-8
import pytest
 
@pytest.fixture()
def login():
    print(\'输入账号,密码先登录\')
 
@pytest.fixture()
def open_index():
    print(\'打开首页\')

  

#test_fix1.py
 
#!encoding=utf-8
import pytest
 
def test_s1(login):
    print(\'用例1:登录之后其他动作111\')
 
def test_s2(open_index):
    print(\'用例2:打开首页操作,操作222\')
 
def test_s3(login):
    print(\'用例3:登录之后其他动作333\')
 
if __name__=="__main__":
    pytest.main(\'-s test_fix1.py\')

 

#test_fix2.py
 
#!encoding=utf-8
import pytest
 
def test_s4(login):
    print(\'用例4:登录之后其他动作111\')
 
def test_s5(open_index):
    print(\'用例5:打开首页操作,操作222\')
 
if __name__=="__main__":
    pytest.main(\'-s test_fix2.py\')

 

执行test_fix1.py

 

 

执行test_fix2.py

 

 

2、单独运行test_fix1.py与test_fix2.py都能调用到conftest.py当中的fixture装饰器中的方法,这样就能实现一些公共的操作可以单独被调用

3、如果.py文件调用conftest.py调用不到时会报以下错误

==================================== ERRORS ====================================
__________________________ ERROR at setup of test_s1 ___________________________
file /Users/luozelin/Desktop/pytest/pytest_demo/test_fix1.py, line 4
  def test_s1(login):
E       fixture \'login\' not found
>       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, metadata, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory
>       use \'pytest --fixtures [testpath]\' for help on them.
 
/Users/luozelin/Desktop/pytest/pytest_demo/test_fix1.py:4
__________________________ ERROR at setup of test_s2 ___________________________
file /Users/luozelin/Desktop/pytest/pytest_demo/test_fix1.py, line 7
  def test_s2(open_index):
E       fixture \'open_index\' not found
>       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, metadata, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory
>       use \'pytest --fixtures [testpath]\' for help on them.
 
/Users/luozelin/Desktop/pytest/pytest_demo/test_fix1.py:7
__________________________ ERROR at setup of test_s3 ___________________________
file /Users/luozelin/Desktop/pytest/pytest_demo/test_fix1.py, line 10
  def test_s3(login):
E       fixture \'login\' not found
>       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, metadata, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory
>       use \'pytest --fixtures [testpath]\' for help on them.
 
/Users/luozelin/Desktop/pytest/pytest_demo/test_fix1.py:10
=============================== 3 error in 0.03s ===============================

  


参考原文链接:https://blog.csdn.net/BearStarX/article/details/101000516

以上是关于python学习-pytest-fixture的主要内容,如果未能解决你的问题,请参考以下文章

07-pytest-fixture实现teardown

12-pytest-fixture使用别名

pytest-fixture

pytest-fixture

04-pytest-fixture作用范围

pytest-fixture参数化