Python pytest框架(二)
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 ===========================================
上一篇: pytest框架学习(一)