当前位置: 首页 > 工具软件 > pytest-flask > 使用案例 >

Pytest详解

屈俊远
2023-12-01

1.pytest的setup和teardown函数

1.setup和teardown主要分为:模块级,类级,功能级,函数级

2.存在于测试类内部

函数级:setup()/teardown()

运行于测试方法的始末,即:运行一次测试函数会运行一次setup和teardown

import pytest


class Test:
    #函数级开始
    def setup(self):
        print("xxxx,要 每天开心")
    #函数级结束
    def teardown(self):
        print("xxxx,当然要每天开心")

    def test_a(self):
        print("输出数据a")

    def test_b(self):
        print("输出数据b")


if __name__ == '__main__':
    pytest.main('-vs', 'aaaa.py')

输出代码:

xxxx,要 每天开心
PASSED                                             [ 50%]输出数据a
xxxx,当然要每天开心
xxxx,要 每天开心
PASSED                                             [100%]输出数据b
xxxx,当然要每天开心

类级别:setup_class()和teardown_class()

运行于测试类的始末,即:在一个测试内只运行一次setup_class和teardown_class,不关心测试类内有多少个测试函数。


import pytest


class Test:
    # 类级别中的开始
    def setup_class(self):
        print("-------类级别中的开始")

    # 类级别中的结束
    def teardown_class(self):
        print("-------类级别中的结束")

    def test_a(self):
        print("输出数据a")

    def test_b(self):
        print("输出数据b")


if __name__ == '__main__':
    pytest.main('-vs', 'aaaa.py')

输出代码:

-------类级别中的开始
PASSED                                             [ 50%]输出数据a
PASSED                                             [100%]输出数据b
-------类级别中的结束

2.pytest之fixture

fixture修饰器来标记固定的工厂函数,在其他函数,模块,类或整个工程调用它时会被激活并优先执行,通常会被用于完成预置处理和重复操作。

方法:fixture(scope="function", params=None, autouse=False, ids=None, name=None)
常用参数:

 scope:被标记方法的作用域
 function" (default):作用于每个测试方法,每个test都运行一次
"class":作用于整个类,每个class的所有test只运行一次
 "module":作用于整个模块,每个module的所有test只运行一次
 "session:作用于整个session(慎用),每个session只运行一次
 params:(list类型)提供参数数据,供调用标记方法的函数使用
 autouse:是否自动运行,默认为False不运行,设置为True自动运行

 2.1 fixture(通过参数引用)

import pytest


class Test_fixture:
    @pytest.fixture()
    def before(self):
        print("------->测试开始")

    def test_a(self, before):
        # test_a方法传入了被fixture标识的函数,已变量的形式
        print("------->test_a")


if __name__ == '__main__':
    pytest.main("-vs  aaaa.py")

2.2  fixture(通过函数引用usefixture)

usefixture需要和fixture同时使用

import pytest


@pytest.fixture()
# fixture标记的函数可以应用于测试类外部
def before():
    print("------->看一下这在什么时候执行")


@pytest.mark.usefixtures("before")
class Test_ABC:
    def setup(self):
        print("------->setup")

    def test_a(self):
        print("------->test_a")

    def test_b(self):
        print("------->test_b")


if __name__ == '__main__':
    pytest.main("-vs  aaaa.py")
    pytest.main("-vs  aaaa.py")

执行结果:

------->setup
------->看一下这在什么时候执行
PASSED                                         [ 50%]------->test_a
------->setup
------->看一下这在什么时候执行
PASSED                                         [100%]------->test_b

2.3 fixture(设置作用域为function)

作用于每个方法中

import pytest


@pytest.fixture(scope='function', autouse=True)
# fixture标记的函数可以应用于测试类外部
def before():
    print("------->看一下这在什么时候执行")


class Test_ABC:
    def setup(self):
        print("------->setup")

    def test_a(self):
        print("------->test_a")

    def test_b(self):
        print("------->test_b")


if __name__ == '__main__':
    pytest.main("-vs  aaaa.py")


执行结果:
------->看一下这在什么时候执行     #第一次执行
------->setup
PASSED                                         [ 50%]------->test_a
------->看一下这在什么时候执行      #第二次执行
------->setup
PASSED     

2.4 fixture(设置作用域为class

import pytest


@pytest.fixture(scope='class', autouse=True)
# fixture标记的函数可以应用于测试类外部
def before():
    print("------->看一下这在什么时候执行")


class Test_ABC:
    def setup(self):
        print("------->setup")

    def test_a(self):
        print("------->test_a")

    def test_b(self):
        print("------->test_b")


if __name__ == '__main__':
    pytest.main("-vs  aaaa.py")

------->看一下这在什么时候执行    #只执行一次
------->setup
PASSED                                         [ 50%]------->test_a
------->setup
PASSED                                         [100%]------->test_b

3.跳过测试函数  skip和skipif函数

根据特定的条件,不执行标识的测试函数.
 方法:
     skipif(condition, reason=None)
 参数:
     condition:跳过的条件,必传参数
     reason:标注原因,必传参数
 使用方法:
     @pytest.mark.skipif(condition, reason="xxx") 
import pytest


class Test_ABC:
    def setup_class(self):
        print("------->setup_class")

    def teardown_class(self):
        print("------->teardown_class")

    def test_a(self):
        print("------->test_a")
        assert 1

    @pytest.mark.skipif(2 > 1, reason="跳过该函数")  # 跳过测试函数test_b
    def test_b(self):
        print("------->test_b")
        assert 1


if __name__ == '__main__':
    pytest.main("-vs  aaaa.py")
------->setup_class
PASSED                                         [ 50%]------->test_a
SKIPPED (跳过该函数)                           [100%]
Skipped: 跳过该函数
------->teardown_class

4 函数数据参数化

@pytest.mark.parametrize(args_name,args_value)

args_name:参数名,字符串,多个参数中间用逗号隔开
args_value:参数值(列表,元组,字典列表,字典元组),有多个值用例就会执行多少次,是list,多组数据用元祖类型;传三个或更多参数也是这样传。list的每个元素都是一个元组,元组里的每个元素和按参数顺序一一对应

 例如:
1、传一个参数 @pytest.mark.parametrize('参数名',list) 进行参数化
2、传两个参数@pytest.mark.parametrize('参数名1,参数名2',[(参数1_data[0], 参数2_data[0]),(参数1_data[1], 参数2_data[1])]) 进行参数化

单个参数实例

import pytest


class Test_AAA:

    def setup_class(self):
        print("------->setup_class")

    def teardown_class(self):
        print("------->teardown_class")
    # 单个参数
    @pytest.mark.parametrize("a",[3,4])
    def test_a(self, a):
        print('输出参数aa=%d'%a)


if __name__ == '__main__':
    pytest.main("-vs aaaa.py")

输出结果:

------->setup_class
PASSED                                      [ 50%]输出参数aa=3
PASSED                                      [100%]输出参数aa=4
------->teardown_class

多个参数实例

import pytest


class Test_AAA:

    def setup_class(self):
        print("------->setup_class")

    def teardown_class(self):
        print("------->teardown_class")

    @pytest.mark.parametrize("user, pwd", [("xiaoming", 111111), ("xiaohua", 111111)])
    def test_002(self, user, pwd):
        print(user)
        # assert user == 'xiaohua'
        # assert pwd == 111111


if __name__ == '__main__':
    pytest.main("-vs aaaa.py")

输出代码:

------->setup_class
PASSED                      [ 50%]xiaoming
PASSED                       [100%]xiaohua
------->teardown_class

 类似资料: