pytest基本使用方法:
初识pytest
import pytest
def test_a():
print('我是第一条测试用例')
assert 1
def test_b():
print('我是第二条测试用例')
assert 0
if __name__ == '__main__':
pytest.main(['api.py']) #填写要执行的模块名称
其中 . ,代表执行成功,F代表执行失败
第二种执行方式:
命令行中使用:pytest 模块名称
执行结果与pytest.main([‘api.py’]),结果无异
第三种执行方式:
建立pytest.ini文件并写入以上内容,在命令行中输入命令pytest会默认执行已test开头的且在本目录下的文件
第四种执行方式:
pytest.ini文件其他配置方法
Pytest中setup和teardown函数与jmeter或者unittest中使用方法基本一致
import pytest
class Test_auto(object):
def setup(self):
print('我是setup函数')
def teardown(self):
print('我是teardown函数')
def test_01(self):
print('我是第一条测试用例')
def test_02(self):
print('我是第二条测试用例')
if __name__ == '__main__':
pytest.main(['-s','api.py'])
执行结果为:
可以明显的看出,在每条用例执行时都会执行依次setup函数和teardown函数
生成html测试报告插件
安装方式:
pip install pytest-html
使用方法:
pytest --html = 存储路径/report.html
修改用例执行顺序插件
安装插件:pip install pytest-ordering
默认情况下,测试用例都是按方法名从小到大执行的,我们可用通过这个插件来改变用例的执行顺序
使用方法:
标记被测函数@pytest.mark.run(order = x)
x值的优先级:
0>较小整数>较大整数>无标记>较小负数>较大负数
import pytest
class Test_auto(object):
@pytest.mark.run(order=2)
def test_01(self):
print('我是第一条测试用例')
@pytest.mark.run(order=1)
def test_02(self):
print('我是第二条测试用例')
if __name__ == '__main__':
pytest.main(['-s','pytest_report.py'])
执行结果为:
失败重试插件
安装命令:pip install pytest-rerunfailures
使用方法:pytest --rerun n #n为重试次数
import pytest
class Test_auto(object):
def test_01(self):
print('我是第一条测试用例')
assert 0
def test_02(self):
print('我是第二条测试用例')
assert 1
if __name__ == '__main__':
pytest.main(['-s','pytest_report.py'])
结果为:
fixture使用方法及作用
fixture名称是固定的,在其他函数,模块,类或整个工程调用时他时被激活
使用方法:
fixture装饰器来标记固定的工厂函数,在其他函数,模块,类或这个工程调用他时会被激活并优先执行,通常会被用于完成预置处理和重复操作
pytest.fixture(scope='function', params=None, autouse=Flase, ids =None, name=None)
-scope:被标记的作用域
"function":默认值,表示每个测试方法都要执行一次
"class":作用于整个类,表示每个类的所有测试方法只运行一次
"module":作用于整个模块,每个module的所有测试方法只运行一次
"session":作用于整个session,每次session只运行一次(此方法慎用)
优先级为:session > module > class > function
注意点:低级别的fixture 可以调用高级别的,反之则是被禁止的
-params:list类型,默认为None,接受参数值,对于param里面的每个值,fixture都回去遍历执行一次
-autouse:是否自动运行,默认为Flase,为true时此session中的所有测试函数都会调用fixture
scope为function(一)
import pytest
@pytest.fixture()
def aaa():
print('我是fixture函数')
def test_a(aaa):
print('我是测试用例')
def test_b(aaa):
print('我是测试用例2')
if __name__ == '__main__':
pytest.main("test_fix.py")
结果为:
结果可以看出来,设置以后,所有的结果在执行前都会先执行被@pytest.fixturn标记的结果
scope为function(二)
import pytest
@pytest.fixture()
def aaa():
print('我是fixture函数')
@pytest.mark.usefixtures('aaa') #注意加引号
def test_a():
print('我是测试用例')
@pytest.mark.usefixtures('aaa') #注意加引号
def test_b(aaa):
print('我是测试用例2')
if __name__ == '__main__':
pytest.main("test_fix.py")
结果为:
scope为function(三)
import pytest
@pytest.fixture()
def aaa():
print('我是fixture函数')
@pytest.mark.usefixtures('aaa')
def test_a():
print('我是测试用例')
@pytest.mark.usefixtures('aaa')
def test_b(aaa):
print('我是测试用例2')
@pytest.mark.usefixtures('aaa')
class Test_fix():
def test_c(self):
print('我是测试用例3')
if __name__ == '__main__':
pytest.main("test_fix.py")
结果为:
scope为function(四)并设置autouse为True
import pytest
@pytest.fixture(autouse=True)
def aaa():
print('我是fixture函数')
class Test_fix():
def test_a(self):
print('我是测试用例1')
def test_b(self):
print('我是测试用例2')
if __name__ == '__main__':
pytest.main("test_fix.py")
结果为:
相当于setup函数,在每条测试用例前都会执行一次
温馨提示:如果执行不成功,请用命令行方式执行
scope为class(一)
import pytest
@pytest.fixture(scope='class', autouse=True)
def aaa():
print('\n我是fixture函数')
def test_b():
print('\n我是测试用例1')
def test_c():
print('\n我是测试用例2')
class Test_fix():
def test_c(self):
print('\n我是测试用例3')
def test_d(self):
print('\n我是测试用例4')
if __name__ == '__main__':
pytest.main("test_fix.py")
这个结果需要大家关注一下,因为设置了参数autouse=True,所以在类之外的函数都可以享受到加成效果(因为优先级问题,在fixture使用方法一开始中有说明),而在类里面的测试用例3和测试用例4,这两个函数之前只会执行一次fixture函数
scope为class(二)且不设置autouse=True
import pytest
@pytest.fixture(scope='class')
def aaa():
print('\n我是fixture函数')
def test_b():
print('\n我是测试用例1')
def test_c():
print('\n我是测试用例2')
class Test_fix():
def test_c(self):
print('\n我是测试用例3')
def test_d(self):
print('\n我是测试用例4')
if __name__ == '__main__':
pytest.main("test_fix.py")
结果都没有执行fixtrue函数,此时是不生效的,切记
scope为modele(一)
import pytest
@pytest.fixture(scope='module', autouse=True)
def aaa():
print('\n我是fixture函数')
def test_b():
print('\n我是测试用例1')
class Test_fix():
def test_c(self):
print('\n我是测试用例2')
def test_d(self):
print('\n我是测试用例3')
if __name__ == '__main__':
pytest.main("test_fix.py")
结果为:
scope为modele(二)
import pytest
@pytest.fixture(scope='module', autouse=True)
def aaa():
print('\n我是fixture函数')
@pytest.mark.usefixtures('aaa')
def test_b():
print('\n我是测试用例1')
@pytest.mark.usefixtures('aaa')
class Test_fix():
def test_c(self):
print('\n我是测试用例2')
def test_d(self):
print('\n我是测试用例3')
if __name__ == '__main__':
pytest.main("test_fix.py")
结果为:
当设置为scope=‘module’,无论怎样调用,此模块只执行一次
使用params传递参数,实现参数化
import pytest
@pytest.fixture(params=[1, 2, 3])
def aaa(request): #传入参数request 系统封装参数
return request.param #取列表中单个值(默认方式)
class Test_fix():
def test_a(self, aaa):
print("test_a的值为%s" % aaa)
if __name__ == '__main__':
pytest.main("test_fix.py")
结果为: