场景:在手工执行测试用例时,我们一般会有测试执行的前置条件,以及测试执行完成的后置条件;
比如:测试一个商城把商品加入购物车,前置条件就是需要用户登录,登录完成后执行加车操作并进行判断是来通过,测试结束后置条件就是清理购物车为其他测试用例还原环境;
在常用的一些测试框架中setup一般用于在测试执行之前执行的操作即执行前置条件,teardown用于在测试执行完成后需要执行的操作即后置条件;在pytest中setup和teardown分为四个级别
●模块级(setup_module/teardown_module)开始于模块(.py)始末调用,全局的
●函数级(setup_function/teardown_function)只对函数用例生效,在函数始末调用(不在类中,在类外部)
●类级(setup_class/teardown_class)在类始末调用
●方法级(setup_method/teardown_method)在方法始末调用(在类中)
●方法级(setup/teardown)在方法始末调用(在类中)
●yield:yield前相当于setup,yield后相当于teardown,scpoe=”module”与yield组合,相当于setup_module和teardown_module
调用顺序是:
setup_module>setup_class>setup_method>setup>teardown>teardown_method>teardown_class>teardown_module
# test_mod4.py
def setup_module():
print("setup_module整个.py模块只执行一次")
def teardown_module():
print("teardown_module整个.py模块只执行一次")
class TestMod4:
def setup_class(self):
print("setup_class测试类前执行")
def teardown_class(self):
print("teardown_class测试类后执行")
def setup(self):
print("setup每个测试方法前执行")
def teardown(self):
print("teardown每个测试方法后执行")
def test_07(self):
print("正在执行测试用例-------test_07")
def test_08(self):
print("正在执行测试用例-------test_08")
运行结果
test_mod4.py::TestMod4::test_07 setup_module整个.py模块只执行一次
setup_class测试类前执行
setup每个测试方法前执行
PASSED [ 50%]正在执行测试用例-------test_07
teardown每个测试方法后执行
test_mod4.py::TestMod4::test_08 setup每个测试方法前执行
PASSED [100%]正在执行测试用例-------test_08
teardown每个测试方法后执行
teardown_class测试类后执行
teardown_module整个.py模块只执行一次
从上面代码可以看出整个test_mod4.py中setup和teardown执行顺序是
1、先执行setup_module( );
2、执行setup_class( );
3、执行setup( )/setup_method;
4、执行teardown( )/teardown_method;
5、执行teardown_class( );
6、最后执行teardown_module( );
函数与类混合
def setup_module():
print("setup_module整个.py模块只执行一次")
def teardown_module():
print("teardown_module整个.py模块只执行一次")
def setup_function():
print("setup_function每个测试函数执行前执行")
def teardown_function():
print("teardown_function每个测试函数执行后执行")
def test_func_09():
print("正在执行测试函数--------test_func_09")
def test_func_10():
print("正在执行测试函数-------test_func_10")
class TestMod4:
def setup_class(self):
print("setup_class测试类前执行")
def teardown_class(self):
print("teardown_class测试类后执行")
def setup(self):
print("setup每个测试方法前执行")
def teardown(self):
print("teardown每个测试方法后执行")
def test_07(self):
print("正在执行测试用例-------test_07")
def test_08(self):
print("正在执行测试用例-------test_08")
执行结果:
test_mod4.py::test_func_09 setup_module整个.py模块只执行一次
setup_function每个测试函数执行前执行
PASSED [ 25%]正在执行测试函数--------test_func_09
teardown_function每个测试函数执行后执行
test_mod4.py::test_func_10 setup_function每个测试函数执行前执行
PASSED [ 50%]正在执行测试函数-------test_func_10
teardown_function每个测试函数执行后执行
test_mod4.py::TestMod4::test_07 setup_class测试类前执行
setup每个测试方法前执行
PASSED [ 75%]正在执行测试用例-------test_07
teardown每个测试方法后执行
test_mod4.py::TestMod4::test_08 setup每个测试方法前执行
PASSED [100%]正在执行测试用例-------test_08
teardown每个测试方法后执行
teardown_class测试类后执行
teardown_module整个.py模块只执行一次
断言
assert 用于判断真假
- assert xx 判断xx为真
- assert not xx 判断xx不为真
- assert a in b 判断b包含a
- assert a == b 判断a等于b
- assert a != b 判断a不等于b
```python
mod2_test.py
def test_three(): print(“执行测试用例test_three”) a = 1 b = 1 assert a==b
def test_four(): print(“执行测试用例test_four”) a = 1 b = 2 assert a == b
命令行:pytest -vs mod2_test.py 结果: def test_four(): print(“执行测试用例test_four”) a = 1 b = 2
assert a == b
E assert 1 == 2 E +1 E -2
mod2_test.py:13: AssertionError FAILED mod2_test.py::test_four - assert 1 == 2
通过Pytest执行这两条用例时,test_four测试用例断言失败
```python
# test_mod5.py
def test_11():
print("正在执行测试用例-------test_11")
a = ['a','b','c',1,2,3]
b = 'a'
assert b in a
def test_12():
print("正在执行测试用例-------test_12")
x = 'a'
y = 'b'
assert x != y
def test_13():
print("正在执行测试用例-------test_13")
assert 3>2
命令行:pytest -vs test_mod5.py
结果:
test_mod5.py::test_11 正在执行测试用例-------test_11
PASSED
test_mod5.py::test_12 正在执行测试用例-------test_12
PASSED
test_mod5.py::test_13 正在执行测试用例-------test_13
PASSED
修改下上述代码,看assert如果失败后,是否还是执行后续代码
def test_13():
print("正在执行测试用例-------test_13")
assert 3>2
print("assert后执行")
def test_14():
print("正在执行测试用例-------test_13")
assert 1>2
print("assert后执行")
命令行:pytest -vs test_mod5.py::test_13
结果:
test_mod5.py::test_13 正在执行测试用例-------test_13
assert后执行
PASSED
命令行:pytest -vs test_mod5.py::test_14
结果:
def test_14():
print("正在执行测试用例-------test_13")
> assert 1>2
E assert 1 > 2
test_mod5.py:21: AssertionError
=============================================================================== short test summary info ================================================================================
FAILED test_mod5.py::test_14 - assert 1 > 2
在上述代码中测试用例test_13, test_14在assert后都有print语句,当assert失败时,则不会执行assert后续代码,即assert一条测试用例中,只可实现一次断言
pytest-assume
安装:pip install pytest-assume
通过 pytest.assume( 表达式 )调用
import pytest
def test_15():
print("正在执行测试用例-------test_15")
pytest.assume(1>2)
pytest.assume('a'=='b')
pytest.assume(0 in [1,2,3,4])
pytest.assume( 1 != 2)
print("assert后执行")
命令行:pytest -vs test_mod5.py::test_15
结果:
test_mod5.py::test_15 正在执行测试用例-------test_15
assert后执行
FAILED
======================================================================================= FAILURES =======================================================================================
_______________________________________________________________________________________ test_15 ________________________________________________________________________________________
tp = <class 'pytest_assume.plugin.FailedAssumption'>, value = None, tb = None
def reraise(tp, value, tb=None):
try:
if value is None:
value = tp()
if value.__traceback__ is not tb:
> raise value.with_traceback(tb)
E pytest_assume.plugin.FailedAssumption:
E 3 Failed Assumptions:
E
E test_mod5.py:29: AssumptionFailure
E >> pytest.assume(1>2)
E AssertionError: assert False
E
E test_mod5.py:30: AssumptionFailure
E >> pytest.assume('a'=='b')
E AssertionError: assert False
E
E test_mod5.py:31: AssumptionFailure
E >> pytest.assume(0 in [1,2,3,4])
E AssertionError: assert False
d:\program files (x86)\python39\lib\site-packages\six.py:702: FailedAssumption
=============================================================================== short test summary info ================================================================================
FAILED test_mod5.py::test_15 - pytest_assume.plugin.FailedAssumption:
================================================================================== 1 failed in 0.36s ===================================================================================
在test_15中有4个断言,其中3个断言是失败不成立的,即该条用例,只有所有断言都通过了该测试用例都定义为PASSED,否则为FAILED