pytest 前置、后置方法, 数据驱动

夹具, 数据驱动

1.pytest默认前置、后置方法

1.1 用例级别前置, 后置方法

无论用例执行成功或者失败,前置、后置方法都会执行
setup: 在执行每一个用例之前会先执行setUp,常用于执行用例时所需的参数依赖,创建资源等操作
teardown: 在每一个用例执行完毕后会执行tearDown,常用于用例生成的测试数据,资源清理等操作

    def setup(self):
        print("\n--------------------------")
        print("setup: 用例级别前置方法")


    def teardown(self):
        print("\nteardown: 用例后置方法")
        print("--------------------------")

执行结果:
image

1.2 测试类级别前置,后置方法

setup_class: 测试类类执行用例前会先执行setup_class,常用于测试类执行用例开始时的资源创建, 数据库连接,日志对象创建等等操作
teardown_class: 测试类执行所有用例完毕后会执行teardown_class,常用于测试类执行用例结束后的资源清理,数据连接销毁,日志对象销毁等

    def setup_class(self):
        print("\n--------------------------")
        print("setup_class: 类前置方法")

    def teardown_class(self):
        print("\nteardown_class: 类后置方法")
        print("--------------------------")

执行结果:
image

2. @pytest.fixture()自定义前置、后置方法

2.1 文件模块中使用

可在文件模块中定义个方法使用@pytest.fixture()进行修饰,可当做前、后置方法使用

  • 使用方法:
    1.定义前、后置方法, 使用装饰器@pytest.fixture 修饰方法
    2.将所需要使用此前、后置方法的用例,将方法名作为参数传入用例方法

  • pytest.fixture()参数说明:
    scope:

    • 默认参数fucntion表示为用例级前、后置
    • class表示为类级别前、后置
    • module表示为模块级前、后置
    • session 表示为会话级别前、后置方法,在一次运行前,后会执行

    aotuse: 默认为False, 表示不会自动执行此方法, True表示自动执行前、后置方法,不需要在用例方法参数中传入自定义方法

代码:

# -*- coding:utf-8 -*-
import pytest

#自定义前后、置方法,scope="function", 表示为方法级前、后置方法, scope默认是function
@pytest.fixture(scope="function")
def my_fixture():
    print("\n---------用例前置方法---------")
    yield
    print("\n---------用例后置方法---------")


class GetAccountTest:

    #在用例中传入自定义方法,表示此用例使用前、后置方法
    #当@pytest.fixture 装饰器,aotuse参数为True时,不需要传入自定义方法, 所有用例都会执行前、后置
    def get_all_test(self, my_fixture):
        print("执行用例 >>> 获取所有账户")

运行结果:
image

2.2 全局使用

使用配置文件conftest.py 结合@pytest.fixture使用
conftest.py可一般使用在模块目录下,或者根目录下

2.2.1 模块目录中使用conftest.py

在模块目录下创建conftest.py
image

定义方法:

conftest.py
# -*- coding:utf-8 -*-
import pytest

@pytest.fixture(scope="class", autouse=True)
def class_fixture():
    print("\n---------conftest.py中的 类前置方法---------")
    yield
    print("\n---------conftest.py中的 类例后置方法---------")

执行结果:
可以看到当前目录下的所有用例都执行了,定义的类前置方法
image

2.2.2 多级目录中使用conftest.py

多级目录中也可以一起使用, 方法名不可以相同
如:
在testcase, 以及子目录account中都创建了conftest.py
image

testcase/conftest.py

# -*- coding:utf-8 -*-
import pytest


@pytest.fixture(scope="class", autouse=True)
def testcase_class_fixture():
    print("\n---------testcase.conftest.py中的 类前置方法---------")
    yield
    print("\n---------testcase.conftest.py中的 类例后置方法---------")


testcase/account/conftest.py

# -*- coding:utf-8 -*-
import pytest

@pytest.fixture(scope="class", autouse=True)
def class_fixture():
    print("\n---------testcase.account.conftest.py中的 类前置方法---------")
    yield
    print("\n---------testcase.account.conftest.py中的 类例后置方法---------")

执行结果:
先执行父目录中的方法,再执行子目录中的方法
image

2.2.3 定义多个级别的前、后置方法

如果想同时使用,方法级别,类级别的前、后置方法如下:
conftest.py

# -*- coding:utf-8 -*-
import pytest


@pytest.fixture(scope="class", autouse=True)
def class_fixture():
    print("\n---------conftest.py中的 类前置方法---------")
    yield
    print("\n---------conftest.py中的 类例后置方法---------")


@pytest.fixture(scope="function", autouse=True)
def func_fixture():
    print("\n---------conftest.py中的 用例前置方法---------")
    yield
    print("\n---------conftest.py中的 用例后置方法---------")

执行结果:
可以看到,用例级别和类级别的前、后置方法都执行了
image


如果只需要一部分用例需要前后置方法时:
autouse: 不使用此参数(默认False),或者参数为False
conftest.py

# -*- coding:utf-8 -*-
import pytest


@pytest.fixture(scope="class", autouse=False)
def class_fixture():
    print("\n---------conftest.py中的 类前置方法---------")
    yield
    print("\n---------conftest.py中的 类例后置方法---------")


@pytest.fixture(scope="function", autouse=False)
def func_fixture():
    print("\n---------conftest.py中的 用例前置方法---------")
    yield
    print("\n---------conftest.py中的 用例后置方法---------")

case:

class GetAccountTest:
	#在需要前、后置方法的用例上传入方法名
    def get_all_test(self, class_fixture, func_fixture):
        print("执行用例: 获取所有账户......")

    def get_account_test(self):
        print("执行用例: 获取单个账户")

执行结果:
可查看到,只有传入前、后置方法的用例,才会执行前、后置方法,其他用例时不会执行
image

3. @pytest.fixture()使用数据驱动

  • pytest.fixture()参数说明:
    params: 可接收列表以及元祖类型参数,作为参数化
    name:起一个别名,那么在传入用例时就需要使用别名传入

代码:

# -*- coding:utf-8 -*-
import pytest


@pytest.fixture(params=["account1", "account2", "account3"], name="data")
def account_list(request):
    return request.param


class CreateAccountTest:

    def create_account_test(self, data):
        print("执行用例: 创建账户:{}.......\n".format(data))

执行结果:
image

4. @pytest.fixture()数据驱动和前后置同时使用

数据驱动和前后置方法可以,写在同一个方法中,非常灵活, 不过建议还是区分开使用

# -*- coding:utf-8 -*-
import pytest


@pytest.fixture(params=["account1", "account2", "account3"], name="account")
def func_fixture(request):
    print("\n---------用例前置方法---------")
    yield request.param
    print("\n---------用例后置方法---------")


class CreateAccountTest:

    def create_account_test(self, account):
        print("执行用例: 创建账户:{}.......".format(data))

执行结果:
image

5. pytest.mark.parametrize 数据驱动

pytest.mark.parametrize 可接收两个参数,
args1: 参数名
args: 接收一个列表,元祖参数

5.1 单个数据参数化

    @pytest.mark.parametrize("name", ["张三", "李四", "王五"])
    def create_account_test(self, name):
        self.log_info("执行用例: 创建账户:{}.......".format(names))

执行结果:
image

5.2 复杂参数


    @pytest.mark.parametrize("user", [{"name": "张三", "age": 18}, {"name": "李四", "age": 28}])
    def create_account_test(self, user):
        self.log_info("执行用例: 创建账户:{}.......".format(user))

执行结果:image

5.3 复杂参数解包

    @pytest.mark.parametrize("name,age", [{"name": "张三", "age": 18}, {"name": "李四", "age": 28}])
    def create_account_test(self, name, age):
        self.log_info("执行用例: 创建账户:{} , 年龄: {}.......".format(name, age))

执行结果:
image

posted @ 2020-07-14 04:16  silence022  阅读(661)  评论(0)    收藏  举报