pytest编写规范
- 测试文件以test_开头或者以_test结尾
- 测试类以Test开头并且不能带有init方法
- 测试函数以test_开头
创建demo文件 src/demo.py
def add(a,b):
return a + b
创建测试用例文件 testcase/test_demo.py
from src.demo import add
def test_add():
assert add(1,2)==3
assert add(1,-1)==3
assert add(3,4)==7
执行
pytest test_demo.py
pytest运行
pip install 插件名称
pytest-sugar:显示执行的进度条
pytest-assume:一次执行完,不会因某个测试用例的失败而告终
def test_add():
assert add(1, 2) == 3
assert add(1, 0) == 2
assert add(1, -1) == 0
执行结果:
可以看出上面 add(1, -1) == 0 没有被执行
使用pytest-assume
def test_add(self):
pytest.assume(add(1, 2) == 3)
pytest.assume(add(1, 0) == 2)
pytest.assume(add(1, -1) == 0)
设置用例的执行顺序
参考文档 https://pytest-ordering.readthedocs.io/en/develop/
- setup_module
- setup_class
- setup_method
- teardown_method
- teardown_class
- teardown_module
import logging
import pytest
logging.basicConfig(level=logging.DEBUG)
def setup_module():
logging.info("setup_module")
def teardown_module():
logging.info("teardown_module")
class TestPytestObject2:
def test_three(self):
assert [1,3]==[1,2]
def test_four(self):
assert {"1":"ss","2":"sss"}
class TestPytestObject:
@classmethod
def setup_class(self):
logging.info("setupclass")
def setup_method(self):
logging.info("setup")
@pytest.mark.run(order=2)
def test_one(self):
assert 1==1
@pytest.mark.run(order=1)
def test_two(self):
assert True == False
def teardown_method(self):
logging.info("teardown")
@classmethod
def tear_down(cls):
logging.info("teardown_class")
pytest-selenium
pytest-play
pytest-rerunfailures:重新运行失败的用例
执行方式
pytest -reruns 3 test-demo.py #3代表失败后重新运行的次数,如果加上正常运行的是4次
pytest-allure
pytest-datadir
pytest-datafiles
pytest --help
pytest --collect-only:查看本目录下有多少测试用例
pytest与unittest区别
unittest
- 测试文件必须先 import unittest
- 测试类必须继承unittest.TestCase
- 测试方法必须以“test_”开头
- 测试类必须要有unittest.main()方法
- unittest只有setup/teardown装载测试用例
pytest
- 测试文件名必须以“test_”开头
- 测试类以Test开头,并且不能带有 init 方法
- 测试方法必须以“test_”开头
- 除了有setup/teardown,还能更自由的定义fixture装载测试用例
compare
运行方式
一个简单的例子
# test_class.py
class TestClass:
def test_one(self):
a = "hello"
assert 'e' in a
def test_two(self):
b = "hello"
assert hasattr(b,'check')
1.cmd运行
- cd到test_class.py所在的文件夹
- 执行pytest -q test_class.py
- 或者执行py.test
2.pycharm下运行
- 可直接运行class
- 可写个main函数运行
if __name__ == "__main__" :
pytest.main("-q test_class.py")
装饰器
装载运行级别:
- 模块级 (setup_module 和 teardown_module)
- 类级(setup_class)和(teardown_class),只在类中前后运行一次。
- 方法级(setup_method)和(teardown_method),开始与方法的始末,在类中
- 类里面(setup)和(teardown),运行在调用方法的前后
- 函数级(setup_function)和 (teardown_function),只对函数用例生效,不在类中
简单的例子如下:
#test_module.py
import pytest
def setup_module(self):
print("setup_module:整个.py模块只执行一次")
def teardown_module(self):
print("teardown_module:整个test_module.py模块只执行一次")
def setup_function():
print("setup_function:每个用例开始前都会执行")
def teardown_function():
print("teardown_function:每个用例结束后都会执行")
#模块中的用例
class TestClass:
def test_one(self):
a = "hello"
assert 'e' in a
def test_two(self):
b = "hello"
assert hasattr(b,'check')
# 测试类
Class TestCase:
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_three(self):
print("正在执行测试类----test_three")
x = "this"
assert 'h' in x
def test_four(self):
print("正在执行测试类----test_four")
x = "hello"
assert hasattr(x, 'check')
if __name__ == '__main__':
pytest.main(["-s","test_module.py"])
运行的结果:
collected 4 items
test_module.py setup_module:整个.py模块只执行一次
setup_function:每个用例开始前都会执行
正在执行测试模块----test_one
.teardown_function:每个用例结束后都会执行
setup_function:每个用例开始前都会执行
正在执行测试模块----test_two
Fteardown_function:每个用例结束后都会执行
setup_class:所有用例执行之前
setup:每个用例开始前都会执行
正在执行测试类----test_three
.teardown:每个用例结束后都会执行
setup:每个用例开始前都会执行
正在执行测试类----test_four
Fteardown:每个用例结束后都会执行
teardown_class:所有用例执行之后
teardown_module:整个test_module.py模块只执行一次