Popular on the whole network, interface automated testing framework-fixture function usage, one article to get through...


Preface

setup and teardown can perform some operations before or after the test case is executed, but this is globally effective for the entire test script;

If you want to log in before executing some use cases, and do not need to log in before executing some use cases, we cannot achieve this scenario by using setup and teardown. At this time, we need to use the fixture function.

1. fixture function

fixture(scope="function", params=None, autouse=False, ids=None, name=None)

Parameter Description:

1) scope: the scope of the fixture function;
Optional values: function (default), class, module, session

function: Acts on each method or function, each method or function is run once
class: Acts on the entire class, all tests in each class are run only once
module: applies to the entire module, and all tests in each module are run only once.
session: applies to the entire session, and the entire session is only run once (use with caution )

2) params: list type;
An optional parameter list;
It will call the method marked by fixture multiple times and all The test case using this fixture;
defaults to None; the current call parameters can be obtained with request.param.

3) autouse: If it is True, the fixture will be activated for all test cases, and the method marked by the fixture will be automatically run when running the test case;
If it is False, it is required Explicitly specify to activate the fixture, it will not run automatically.

4) ids: List of id strings, corresponding to params, so they are also part of the test. If ids are not provided, they will be automatically generated from params.

5) name: the name of the fixture. Defaults to the function name marked by the fixture decorator.

2. Use of fixtures

1) Reference the fixture function through parameters

Example:

# file_name:test_fixture.py


import pytest


class Test_A:

@pytest.fixture()
def before(self):
	print("\n--------before fixture has ran--------")

def test_a(self, before):    # test_a方法以参数的形式传入了被fixture标记的函数,fixture的名称默认为被fixture标记的函数名
	print('-------test_a has ran-------')
	assert 1


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

2) Reference the fixture function by using the name parameter

① The name parameter indicates the renaming of the fixture;
② Generally speaking, the test function using the fixture will pass the function name of the fixture as a parameter, but pytest also allows the fixture to be renamed.

Example 1:

# file_name:test_fixture.py


import pytest


class Test_A:

    @pytest.fixture(name="before_fixture_name")
    def before(self):
        print("\n--------before fixture has ran--------")

    def test_a(self, before_fixture_name):    # test_a方法以参数的形式传入了被fixture标记的函数,这里的fixture名称为:before_fixture_name,如果不设置name参数,则fixture的名称默认为被fixture标记的函数名
        print('-------test_a has ran-------')
        assert 1


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

Example 2:
After renaming the fixture function, it cannot be called using the function name of the fixture function. It can only be called through the new name of the fixture function.

A1

3) Reference the fixture function in the form of @pytest.mark.usefixtures(‘fixture function name’) function

Example:

# file_name: test_fixture.py


import pytest


@pytest.fixture()  # 被fixture标记的函数也可以应用在测试类的外部,使用@pytest.mark.usefixtures()装饰器来引用
def before():
    print("\n--------before fixture has ran--------")


@pytest.mark.usefixtures("before")  # 通过使用usefixtures()来引用fixture,此时usefixtures()函数的入参是fixture函数的函数名
class Test_A:

    def test_a(self):
        print('-------test_a has ran-------')
        assert 1


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

4) Execute the fixture function by default by setting autouse=True

①The autouse parameter of the fixture function defaults to False;

②If the autouse parameter of the fixture function is True, each test function will automatically call the fixture function without passing in the fixture function name.

Example:

# file_name: test_fixture.py


import pytest


@pytest.fixture(autouse=True)  # 通过参数autouse=True来设置fixture默认运行
def before():
    print("\n--------before fixture has ran--------")


class Test_A:

    def test_a(self):
        print('-------test_a has ran-------')
        assert 1

    def test_b(self):
        print('-------test_b has ran-------')
        assert 1


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

5) Set the fixture scope to function

Example:

# file_name: test_fixture.py


import pytest


@pytest.fixture(scope="function", autouse=True)  # 作用域设置成function,通过参数autouse=True来设置fixture默认运行
def before():
    print("\n--------before fixture has ran--------")


class Test_A:

    def test_a(self):
        print('-------test_a has ran-------')
        assert 1

    def test_b(self):
        print('-------test_b has ran-------')
        assert 1


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

6) Set the fixture scope to class

Example:

# file_name: test_fixture.py


import pytest


@pytest.fixture(scope="class", autouse=True)  # 作用域设置成class,通过参数autouse=True来设置fixture默认运行
def before():
    print("\n--------before fixture has ran--------")


class Test_A:

    def test_a(self):
        print('-------test_a has ran-------')
        assert 1

    def test_b(self):
        print('-------test_b has ran-------')
        assert 1


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

7) Use of fixture return value

Example:

# file_name: test_fixture.py


import pytest


@pytest.fixture()
def return_data():
    print("\n--------before fixture has ran--------")
    return 2    # 返回值


class Test_A:

    def test_a(self, return_data):
        print('-------test_a has ran-------')
        assert 1 == return_data # 拿到返回值做断言


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

8) Use of params parameters of fixture

①The params parameter is an optional parameter list of the fixture function and supports passing in the list;
②The default is None when this parameter is not passed;
③ Each param value fixture function will be called and executed once, similar to a for loop.
④ Can be used with parameter ids as the identifier of each parameter, similar to the role of ids when parameterizing use cases.

Example:

# file_name: test_fixture.py


import pytest


@pytest.fixture(params=[1, 2, 3])
def return_data(request):   # 传入参数request,request系统内置的fixture
    print("\n--------before fixture has ran--------")
    return request.param  # 通过request.param 获取当前传入的参数


class Test_A:

    def test_a(self, return_data):
        print('-------test_a has ran,return_data的值为:{}-------'.format(return_data))
        assert 1 == return_data  # 拿到返回值做断言


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

operation result:

A2

From the results we can see that the test case was executed 3 times. Setting the params parameter will cause the function marked by the fixture to be called multiple times, and the test case using the fixture function will also be executed multiple times.

A3

9) The params parameter of fixture is used in combination with the ids parameter.

① Before the fixture function is configured with the ids parameter: the identifier after the use case is executed is the incoming params parameter.

A4

②After the fixture function configures the ids parameter: the identifier after the use case is executed is the passed in ids parameter. And corresponds one-to-one with the params parameters.

A5

10) Mutual calls of fixture functions (dependency between fixture functions and fixture functions)

Example 1:

import pytest
# fixtrue作为参数,互相调用传入
@pytest.fixture()
def account():
    a = "account"
    print("第一层fixture")
    return a
    
#Fixture的相互调用一定是要在测试类里调用这层fixture才会生次,普通函数单独调用是不生效的
@pytest.fixture()   
def login(account):
    print("第二层fixture")

class TestLogin:
    def test_1(self, login):
        print("直接使用第二层fixture,返回值为{}".format(login))

    def test_2(self, account):
        print("只调用account fixture,返回值为{}".format(account))


if __name__ == '__main__':
    pytest.main()

Example 2:
If a fixture function depends on another fixture function, @pytest.mark.usefixtures() cannot call the dependent fixture function at this time. This method of calling will not take effect. Instead, it needs to be passed through a function to take effect.

# test_fixture_02.py
import pytest


@pytest.fixture()
def login_weibo():
    print("==============登陆微博===============")


@pytest.fixture()
# @pytest.mark.usefixtures("login_weibo")  #这种方式不会生效
def get_weibo_data(login_weibo):  # 这种方式才会生效
    """fixture函数依赖,需要用传递函数的方式"""
    print("=============获取微博数据==============")


@pytest.mark.demo
class TestMyCode:

    @pytest.mark.usefixtures("get_weibo_data")
    def test_fixture_005(self):
        """fixture函数在测试脚本文件中"""
        assert 1 == 1

operation result:

A6

Note:
① Even if fixture functions support mutual calls, ordinary functions using fixtures directly are not supported. They must be called within the test function for the step-by-step call to take effect. .

② When there are multiple layers of fixture functions called, the last layer of fixture functions is executed first, instead of the fixture function passed in to the test function.

③The value of the upper fixture function will not be returned automatically. The logic here is similar to that of functions calling each other. [The function call value needs to be assigned to a variable and used]

The following is the most comprehensive software testing engineer learning knowledge architecture system diagram in 2023 that I compiled.

1. Python programming from entry to proficiency

Please add image description

2. Practical implementation of interface automation projects

Please add image description

3. Web automation project actual combat

Please add image description

4. Practical implementation of App automation project

Please add image description

5. Resumes of first-tier manufacturers

Please add image description

6. Test and develop DevOps system

Please add image description

7. Commonly used automated testing tools

Please add image description

8. JMeter performance test

Please add image description

9. Summary (little surprise at the end)

Behind every success is hard work and persistence. Believe in your ability to realize your dreams. No matter how many difficulties and obstacles lie ahead, they cannot stop you from reaching your destination.

Everyone has endless possibilities. The key is to believe in yourself, move forward courageously, not be afraid of failure or setbacks, and constantly challenge yourself. In the end, you will achieve extraordinary success.

There is no perfection in life. Only by continuous improvement, bravely pursuing your dreams, constantly exploring the unknown world, and accumulating knowledge and experience can you eventually become a truly strong person.

Guess you like

Origin blog.csdn.net/m0_70102063/article/details/134462480