[pytest] Fourth, the fixture() of pytest realizes part of the front and back, and the detailed explanation of the use of fixture combined with conftest.py

I. Introduction:

1) setup and teardown: realize the front and back of all use cases; but in practical applications, we need to configure the front and back of some use cases more flexibly; 2) fixture(): fixture firmware, or fixtures, can
realize some or all of the use cases Front and rear; fixture is a decorator that can be used to decorate functions, classes, etc.

  1. Fixture naming rules are more flexible, you can name it arbitrarily
  2. The front and back of the fixture are distinguished by the keyword yield, the code before yield is the pre-operation, and the code after yield is the post-operation
  3. Pre- and post-operations can exist independently: that is, there can be only pre-operations, or only post-operations

Second, the application of fixtures:

  1. define a function
  2. Turn it into a fixture through the decorator method
    @pytest.fixture()
    def exe_database_sql():
    print("Execute SQL query statement")
  3. It needs to correspond to the front and rear use cases, and call the name of the fixture by passing parameters
    def test_tangseng(self,exe_database_sql):
    print("0130 test login successful - Tang Seng")
import pytest

@pytest.fixture()
def exe_database_sql():
    print("执行SQL查询语句")

class TestLoginA():

    def test_tangseng(self,exe_database_sql):
        print("0130类测试登录成功-唐僧")

    def test_sunwukong(self):
        print("0130测试登录成功-孙悟空")

    def test_zhubajie(self):
        print("0130测试登录成功-猪八戒")

    def test_shaheshang(self):
        print("0130测试登录成功-沙和尚")

3. Detailed explanation of the 5 parameters of fixture, one: scope (scope)

scope: Control the scope of the fixture: session>module>class>function, the default scope of the fixture is function;
(1) function: it will be called before and after the function or method

1. Manual call method: add the name of the fixture to the parameters of the test case
2. If the fixture has a return value through return or yield, you can pass the corresponding value to the test case, and the value is passed by the name of the fixture – Data-driven, parameterized use cases

import pytest

#作用域为function
@pytest.fixture(scope="function")
def my_fixture():
    print("这是前置的方法,可以实现部分以及全部用例的前后置")
    yield
    print("这是后置的方法,可以实现部分以及全部用例的前后置")

class TestLogin:

    def test_login_01(self):
        print("\n测试01号登录成功")
    
    # my_fixture函数可以当参数,传入来调用
    def test_login_02(self,my_fixture):
        print("\n测试02号登录成功")

    def test_login_03(self):
        print("\n测试03号登录成功")

    def test_login_04(self):
        print("\n测试04号登录成功")

    def test_login_05(self):
        print("\n测试05号登录成功")

(2) class: execute before and after each class (there can be multiple methods in a class)

1. Manual call method: Add the @pytest.mark.usefixtures("exe_database_sql") decorator on top of the class to call

import pytest
from common.common_util import CommonUtil

@pytest.fixture(scope="class",autouse=False)
def exe_database_sql():
    print("执行SQL查询语句")
    return ":success"

@pytest.mark.usefixtures("exe_database_sql")
class TestLoginA(CommonUtil):

    def test_tangseng(self):
        print("0130类测试登录成功-唐僧")

    def test_sunwukong(self):
        print("0130测试登录成功-孙悟空")

(3) module: each .py file is called once, and there are multiple functions and classes in the file

(4) session: Executed before and after the entire project session, multiple files are called once, and can be called across .py files, each .py file is a module

Generally, it will be implemented in combination with the conftest.py file

3. Detailed explanation of the 5 parameters of fixture, the second: autouse (automatic call)

autouse: Control whether the fixture is automatically called and executed
automatically. The default is False
. Manually passing parameters can automatically call the fixture to run the front and rear
insert image description here

3. Detailed explanation of the 5 parameters of fixture, the third: params (parameterization)

params: Used to achieve parameterization and data-driven

  1. Through the request parameter, it is used to receive the return result of the fixture, and return the result content through request.param - it is a fixed usage (request.param does not need to have s here, and reads the parameters in the list one by one)
  2. If there are N sets of parameter data in the list, the use case will be executed N times
  3. All data drivers must use the list format ['Zhang San','Li Si','Wang Wu']
import pytest

@pytest.fixture(scope="function",params=['张三','李四','王五'])
def my_fixture(request):
    print("这是前置的方法,可以实现部分以及全部用例的前后置")
    yield request.param
    print("这是后置的方法,可以实现部分以及全部用例的前后置")

class TestLogin:

    def test_login_01(self):
        print("\n测试01号登录成功")

    # 函数可以当参数,传入来调用
    def test_login_02(self,my_fixture):
        print("\n测试02号登录成功",str(my_fixture))
        print('------------------\n'+str(my_fixture))

    def test_login_03(self):
        print("\n测试03号登录成功")

    def test_login_04(self):
        print("\n测试04号登录成功")

    def test_login_05(self):
        print("\n测试05号登录成功")

Notice:

@pytest.fixture(scope="function",params=['Zhang San','Li Si','Wang Wu']), is the parameter name, with s yield request.param, is the attribute name, without s,
yes Fixed wording.

3. Detailed explanation of the 5 parameters of fixture, the 4th: ids (parameter alias)

ids: cannot be used alone, must be used together with params, the function is: to mark the parameterized content and alias the parameters

Alias ​​the parameterized content to let others know what the parameter passed in means.
The default is: the content of the parameter
is not very effective

insert image description here

3. Detailed explanation of the 5 parameters of the fixture, the fifth: name (rename the fixture)

name: Indicates renaming the name of the fixture

  1. Once renamed, only aliases can be used
  2. The name of the original fixture can no longer be used, calling the original fixture directly will report an error
  3. Must be enclosed in double quotes, such as: name="db"
@pytest.fixture(scope="function",params=reader,ids=['A','B','C'],name="db")

Fourth, the fixture is used in conjunction with the conftest.py file:

--fixture can be used in conftest.

The conftest.py configuration needs to pay attention to the following points:

  1. conftest.py: the name is fixed and cannot be changed; it is a configuration file specially used to store fixtures;
  2. There is no need to import conftest.py, pytest use cases will be automatically searched;
  3. conftest.py and the running use case should preferably be under the same pakage, scope: only works for the current package;
  4. There can be multiple conftest.py files, and multiple fixtures in multiple conftest.py files can be called by the same use case;
  5. scope="session" realizes that multiple .py files use one session across files to complete multiple use cases.
# Time:2022 2022/2/23 13:42
# -*- coding: utf-8 -*-

import pytest
import uiautomator2 as u2
import time


@pytest.fixture(scope="session", autouse=True)
def device():
    d = u2.connect()
    d.unlock()
    time.sleep(1)
    pkg_name = 'com.taobao.taobao'
    currentApp = d.app_list_running()

    if pkg_name in currentApp:
        d.app_stop(pkg_name)

    d.app_start(pkg_name, wait=True)

    print("\n----------APP starts----------")
    print(d.info)
    time.sleep(10)
    yield d
    print("\n----------APP ends----------")

Five, conftest and setup/teardown priority

  • fixture(session)>fixture(class)>setup_class>fixture(function)>setup_function

  • Session level: session of fixture, highest priority

  • Class: the class level priority of fixture is second;

  • Class: setup_class has lower priority than fixture;

  • Function: the function level priority of fixture is again;

  • Function: setup_function has lower priority than fixture(function);

extension:

The difference between return and yield

1. Both return and yield mean return, but there can be no code behind return, and no subsequent code will be executed after the return value; 2. After
yield returns, you can receive the code and continue to execute.

Guess you like

Origin blog.csdn.net/Moonlight_16/article/details/123086959