fixture scope - pytest

This article mainly records: the scope of different parameters of fixture in pytest

1. The parameters of the fixture control the scope of action.
There is a scope parameter in the fixture that can control the scope of the fixture: session > module > class > function

fixture(scope="function", params=None, autouse=False, ids=None, name=None):
    """使用装饰器标记fixture的功能
 可以使用此装饰器(带或不带参数)来定义fixture功能。 fixture功能的名称可以在以后使用
 引用它会在运行测试之前调用它:test模块或类可以使用pytest.mark.usefixtures(fixturename标记。 
 测试功能可以直接使用fixture名称作为输入参数,在这种情况下,夹具实例从fixture返回功能将被注入。

:arg scope: scope 有四个级别参数 "function" (默认), "class", "module" or "session".

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

:arg autouse:  如果为True,则为所有测试激活fixture func 可以看到它。 如果为False(默认值)则显式需要参考来激活fixture

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

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

2. Detailed explanation of socope parameters

  1. The scope parameter is: function

Scope of action: every function or method will be called

class Each class is called once, a class can have multiple method
modules, and each .py file is called once, and there are multiple functions and class
sessions in this file, which are called once by multiple files, and can be called across .py files. A .py file is module
scope="function"
@pytest.fixture() If you do not write parameters, the default is scope="function". Its scope of action is to run once before each test case, and the destruction code is run in the test case run after that.

  • Code demo:
import pytest

@pytest.fixture()
def first():
    print("\n获取用户名")
    a = "yoyo"
    return a

@pytest.fixture(scope="function")
def sencond():
    print("\n获取密码")
    b = "123456"
    return b

def test_1(first):
    '''用例传fixture'''
    print("测试账号:%s" %first)
    assert first == "yoyo"

def test_2(sencond):
    '''用例传fixture'''
    print("测试密码:%s" %sencond)
    assert sencond == "123456"

if __name__ == "__main__":
    pytest.main(["-s", "test_fixture7.py"])

  • operation result:
============================= test session starts =============================
platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: D:\YOYO\fixt, inifile:
plugins: rerunfailures-4.1, metadata-1.7.0, html-1.19.0, allure-adaptor-1.7.10
collected 2 items

test_fixture7.py 
获取用户名
测试账号:yoyo
.
获取密码
测试密码:123456
.

========================== 2 passed in 0.01 seconds ==========================

In addition: the use case is placed in the class as well

  • Code demo:

import pytest

@pytest.fixture()
def first():
    print("\n获取用户名")
    a = "yoyo"
    return a

@pytest.fixture(scope="function")
def sencond():
    print("\n获取密码")
    b = "123456"
    return b

class TestCase():
    def test_1(self, first):
        '''用例传fixture'''
        print("测试账号:%s" % first)
        assert first == "yoyo"

    def test_2(self, sencond):
        '''用例传fixture'''
        print("测试密码:%s" % sencond)
        assert sencond == "123456"

if __name__ == "__main__":
    pytest.main(["-s", "test_fixture7.py"])
scope="class"
  1. The scope parameter is class

When the fixture is at the class level, if there are multiple use cases in a class, and this fixture is called, then this fixture is only executed once before all the use cases in the class start

  • Code demo:

import pytest

@pytest.fixture(scope="class")
def first():
    print("\n获取用户名,scope为class级别只运行一次")
    a = "yoyo"
    return a

class TestCase():
    def test_1(self, first):
        '''用例传fixture'''
        print("测试账号:%s" % first)
        assert first == "yoyo"

    def test_2(self, first):
        '''用例传fixture'''
        print("测试账号:%s" % first)
        assert first == "yoyo"

if __name__ == "__main__":
    pytest.main(["-s", "test_fixture9.py"])
  • operation result:
============================= test session starts ============================
platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: D:\YOYO\fixt, inifile:
plugins: rerunfailures-4.1, metadata-1.7.0, html-1.19.0, allure-adaptor-1.7.10
collected 2 items

test_fixture9.py 
获取用户名,scope为class级别只运行一次
测试账号:yoyo
.测试账号:yoyo
.

========================== 2 passed in 0.13 seconds ==========================
  1. The scope parameter is: module

scope="module"
When the fixture is at the module level, it is only executed once before all use cases in the current .py script start

  • Code demo:
import pytest

@pytest.fixture(scope="module")
def first():
    print("\n获取用户名,scope为module级别当前.py模块只运行一次")
    a = "yoyo"
    return a


def test_1(first):
    '''用例传fixture'''
    print("测试账号:%s" % first)
    assert first == "yoyo"

class TestCase():
    def test_2(self, first):
        '''用例传fixture'''
        print("测试账号:%s" % first)
        assert first == "yoyo"

if __name__ == "__main__":
    pytest.main(["-s", "test_fixture10.py"])
  • operation result:

============================= test session starts =============================
platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: D:\YOYO\fixt, inifile:
plugins: rerunfailures-4.1, metadata-1.7.0, html-1.19.0, allure-adaptor-1.7.10
collected 2 items

test_fixture10.py 
获取用户名,scope为module级别当前.py模块只运行一次
测试账号:yoyo
.测试账号:yoyo
.

========================== 2 passed in 0.14 seconds ===========================
  1. The scope parameter is: session

scope="session"
fixture can be called across .py modules at the session level, that is, when we have multiple use cases of .py files, if multiple use cases only need to call fixture once, then it can be set to scope=" session", and write to the conftest.py file

The conftest.py file name is fixed, and pytest will automatically recognize the file. If you put it in the root directory of the project, you can call it globally. If you put it in a certain package, it will only be valid in that package.

  • Code demo:

(1) conftest.py

import pytest

@pytest.fixture(scope="session")
def first():
    print("\n获取用户名,scope为session级别多个.py模块只运行一次")
    a = "yoyo"
    return a
test_fixture11.py和test_fixture12.py用例脚本

(2)test_fixture11.py

import pytest
def test_1(first):
    '''用例传fixture'''
    print("测试账号:%s" % first)
    assert first == "yoyo"

if __name__ == "__main__":
    pytest.main(["-s", "test_fixture11.py"])

(3) test_fixture12.py

import pytest

def test_2(first):
    '''用例传fixture'''
    print("测试账号:%s" % first)
    assert first == "yoyo"

if __name__ == "__main__":
    pytest.main(["-s", "test_fixture12.py"])
如果想同时运行test_fixture11.py和test_fixture12.py,在cmd执行

(4) Execute the command:pytest -s test_fixture11.py test_fixture12.py

  • Results of the:
============================= test session starts =============================
platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: D:\YOYO\fixt, inifile:
plugins: rerunfailures-4.1, metadata-1.7.0, html-1.19.0, allure-adaptor-1.7.10
collected 2 items

test_fixture11.py .                                                      [ 50%]
test_fixture12.py .                                                      [100%]

========================== 2 passed in 0.03 seconds ===========================

D:\YOYO\fixt>pytest -s test_fixture11.py test_fixture12.py
============================= test session starts =============================
platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: D:\YOYO\fixt, inifile:
plugins: rerunfailures-4.1, metadata-1.7.0, html-1.19.0, allure-adaptor-1.7.10
collected 2 items

test_fixture11.py
获取用户名,scope为session级别多个.py模块只运行一次
测试账号:yoyo
.
test_fixture12.py 测试账号:yoyo
.

========================== 2 passed in 0.03 seconds ===========================

Guess you like

Origin blog.csdn.net/Orange_hhh/article/details/128084191