欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python pytest框架(二)

程序员文章站 2024-02-27 14:24:09
...

pytest 框架结构:

执行用例前后会执行setup,teardown,来增加用例的前置和后置条件
按用例的运行级别可以分为以下几类:
1.模块级(setup_module/teardown_module)在模块始末调用
有多个测试类的时候使用,执行所有测试类之前/之后,只执行一次

2.函数级(setup_function/teardown_function)在函数始末调用(在类外部)
3.类级(setup_class/teardown_class)在类始末调用(在类中)
在该类下,所有用例执行之前/之后,只执行一次
4.方法级(setup_method/teardown_method)在法法始末调用(在类中)
在执行测试用例之前/之后,执行,每执行一个测试用例都要执行一次
5.方法级(setup/teardown)在方法始末调用(在类中)
调用顺序:

setup_module>setup_class>setup_method>setup>teardown>teardown_method>teardown_class>teardown_module
下面验证一下执行顺序:

import pytest
#模块级
#模块执行前
def setup_module():#在所有测试类执行之前执行
    print("\nsetup_module, 有多个测试类的时候使用,执行测试类之前,只执行一次")
#模块级
#模块执行后
def teardown_module():#在所有测试类执行后执行一次
    print("\nsetup_module, 有多个测试类的时候使用,执行完所有测试类之后,只执行一次")
#类级
class Test1(object):
    @classmethod
    def setup_class(self):#在该类下,所有用例执行之前执行一次
        print("\nThis is setup_class1, 执行用例之前,只执行一次")
    @classmethod
    def teardown_class(self):#在该类下所有的用例,执行完以后执行一次
        print("\nThis is teardown_class1, 执行完所有用例以后,只执行一次")

    def setup_method(self):#在执行测试用例之前执行,每执行一个测试用例都要执行一次
        print("\nThis is setup_method1")
        print("在执行测试用例之前执行,每执行一个测试用例都要执行一次")
    def teardown_method(self):
        print("\nThis is teardown_method1")
        print("在执行测试用例之后执行,每执行一个测试用例都要执行一次")
    def test_case3(self):#测试用例
        print("this is case3")
    def test_case4(self):#测试用例
        print("this is case4")

class Test2(object):
    @classmethod
    def setup_class(self):
        print("\nThis is setup_class2,执行用例之前,只执行一次")
    @classmethod
    def teardoem_class(self):
        print("\nThis is teardown_class2, 执行完所有用例以后,只执行一次")
    def setup_method(self):
        print("\nThis is setup_method2")
        print("在执行测试用例之前执行,每执行一个测试用例都要执行一次")
    def teardown_method(self):
        print("\nThis is teardown_method2")
        print("在执行测试用例之后执行,每执行一个测试用例都要执行一次")

    def test_case2(self):
        print("this is case2")
    def test_case1(self):
        print("this is case1")

执行脚本

pytest -vs test_sequence.py

结果分析:

collected 4 items                                                                                      

test_sequence.py::Test1::test_case3 
setup_module, 有多个测试类的时候使用,执行测试类之前,只执行一次

This is setup_class1, 执行用例之前,只执行一次

This is setup_method1
在执行测试用例之前执行,每执行一个测试用例都要执行一次
this is case3
PASSED
This is teardown_method1
在执行测试用例之后执行,每执行一个测试用例都要执行一次

test_sequence.py::Test1::test_case4 
This is setup_method1
在执行测试用例之前执行,每执行一个测试用例都要执行一次
this is case4
PASSED
This is teardown_method1
在执行测试用例之后执行,每执行一个测试用例都要执行一次

This is teardown_class1, 执行完所有用例以后,只执行一次

test_sequence.py::Test2::test_case2 
This is setup_class2,执行用例之前,只执行一次

This is setup_method2
在执行测试用例之前执行,每执行一个测试用例都要执行一次
this is case2
PASSED
This is teardown_method2
在执行测试用例之后执行,每执行一个测试用例都要执行一次

test_sequence.py::Test2::test_case1 
This is setup_method2
在执行测试用例之前执行,每执行一个测试用例都要执行一次
this is case1
PASSED
This is teardown_method2
在执行测试用例之后执行,每执行一个测试用例都要执行一次

setup_module, 有多个测试类的时候使用,执行完所有测试类之后,只执行一次


========================================== 4 passed in 0.01s ===========================================

**

控制用例的执行顺序:

**
pytest加载用例的时候是乱序的,如果想要按指定的顺序来执行用例,可以用pytest-ordering插件,只需要在用例的方法前面加上装饰器,就会通过order对应的number大小顺序执行。
@pytest.mark.run(order=[number]),应用场景:会员查看自己的积分,需要先登录自己的账户,点击查看查看积分,就需要先执行登录的用例,再执行查看的操作。
安装插件:

pip install pytest-ordering

不修改脚本查看一下执行结果

collected 3 items                                                                                      

test_add.py::test_add
PASSED
test_add.py::TestClass::test_one
PASSED
test_add.py::TestClass::test_two FAILED

=============================================== FAILURES ===============================================

修改脚本

import pytest
  
def add(x, y):
    return x + y
@pytest.mark.add
@pytest.mark.run(order=2)
def test_add():
    assert add(1, 10) == 11
    print("第二个测试用例")
class TestClass:
    @pytest.mark.add
    def test_one(self):
        x = "this"
        assert "h" in x
        print("第三个用例")
    @pytest.mark.run(order=1)
    def test_two(self):
        x = "hello"
        assert hasattr(x, "hello")
        print("执行第一个用例")

修改脚本后的执行结果:

collected 3 items                                                                                      

test_add.py::TestClass::test_two FAILED
test_add.py::test_add 第二个测试用例
PASSED
test_add.py::TestClass::test_one 第三个用例
PASSED

=============================================== FAILURES ===============================================

第一个用例,因为是断言失败的用例,所以没有打印出信息,自己调试的话可以改成成功的试试
**

fixtures:

**
fixtures可以用来装饰一个方法,被装饰的方法可以当作一个参数,传入到测试方法中。可以用来完成测试之前的初始化,也可以返回数据给测试函数。
作为一个函数的参数时:
通常使用setup和 teardown来进行资源初始化。应用场景:case1依赖登录,case2不依赖登录,case3依赖登录,这种场景无法使用setup和teardown,可以使用fixture,在方法前加@pytest.fixture(),这样可以将登录用例的方法名以参数的形式传入到方法里,这个方法会先执行登录用例(登录用例前加@pytest.fixture())。
例:

@pytest.fixture()
def test_login():
    print("先执行登录用例")
    return ('token', 'test123')


def test_case1(test_login):
    print("第一个用例依赖登录")
    print(test_login)

def test_case2():
    print("不依赖登录")

def test_case3(test_login):
    print("第三个用例依赖登录")
    print(test_login)

执行结果:

collected 3 items                                                                                      

test_fix.py::test_case1 先执行登录用例
第一个用例依赖登录
('token', 'test123')
PASSED
test_fix.py::test_case2 不依赖登录
PASSED
test_fix.py::test_case3 先执行登录用例
第三个用例依赖登录
('token', 'test123')
PASSED

========================================== 3 passed in 0.03s ===========================================