咖啡网站开发,广告接单网站,网站的做用,wordpress 产品页 如何关联pytest 是一款以python为开发语言的第三方测试#xff0c;主要特点如下#xff1a; 比自带的 unittest 更简洁高效#xff0c;兼容 unittest框架 支持参数化 可以更精确的控制要测试的测试用例 丰富的插件#xff0c;已有300多个各种各样的插件#xff0c;也可自定义扩…pytest 是一款以python为开发语言的第三方测试主要特点如下 比自带的 unittest 更简洁高效兼容 unittest框架 支持参数化 可以更精确的控制要测试的测试用例 丰富的插件已有300多个各种各样的插件也可自定义扩展如pytest-selenium、pytest-html、pytest-rerunfailures、pytes-xdish 可很好的和CI工具结合
安装
pip install pytest测试用例编写规则 测试文件以test_开头 或者 _test结尾 测试类以Test开头并且不能带有 init 方法 测试文件以 test_开头 断言使用基本的 assert 即可
pytest会递归查找当前目录及子目录下所有 以test_开始 或者 _test结尾的python脚本执行其中符合规则的函数和方法不需要显示调用
运行命令cmd进入用例所在目录
pytest folder_name 》直接运行文件夹内符合规则的所有用例pytest test_file.py 》执行某个py文件中的用例pytest test_file.py::test_func 》执行模块内的某个函数节点运行pytest test_file.py::TestClass::test_method 》执行模块内测试类的某个方法节点运行pytest test_file.py::TestClass 》执行模块内某个测试类节点运行pytest test_file.py::TestClass test_file2.py::test_mothod 》多节点运行中间用空格隔开pytest -k pass 》匹配用例名称的表达式含有“pass”的被执行其他的deselectedpytest -k pass or fail 》组合匹配含有“pass” 和 “fail”的被执行pytest -k not pass 》排除运行不含“pass”的被执行pytest -m finished 》标记表达式运行用pytest.mark.finished 标记的用例pytest -m finished and not merged 》多个标记逻辑匹配运行含有finished 不含 merged标记的用例pytest -v 》运行时显示详细信息pytest -s 》显示打印消息pytest -x 》遇到错误就停止运行pytest -x --maxfail2 》遇到两个错误就停止运行pytest --setup-show 》跟踪固件运行pytest -v --reruns 5 --reruns-delay 1 》运行失败的用例间隔1s重新运行5次 pip install pytest-rerunfailurespytest 》多条断言报错后后面的依然执行, pip install pytest-assume断言 pytest.assume(24)pytest -n 3 》3个cpu并行执行测试用例需保证测试用例可随机执行, pip install pytest-xdist分布式执行插件多个cpu或主机执行pytest -v -n auto 》自动侦测系统里cpu的数目pytest --count2 》重复运行测试 pip install pytest-repeatpytest --html./report/report.html 》生成报告此报告中css是独立的分享时会丢失样式pip install pytest-htmlpytest --htmlreport.html --self-containd-html 》合并css到html报告中除了passed所有行都被展开pytest --durations10 》获取最慢的10个用例的执行耗时用例执行顺序控制
pytest 用例执行顺序默认是按字母顺序去执行要控制执行顺序需要安装插件 pytest-orderingpip install pytest-ordering
在测试方法上加上装饰器
pytest.mark.last 最后一个执行
pytest.mark.run(ordern) n1则是第一个执行 Mark
标签的使用方法
注册标签名 / 内置标签--- 在测试用例 / 测试类 / 模块文件 前面加上 pytest.mark.标签名
注册方法
1. 在conftest.py 文件中添加代码
# 单个标签文件内容
def pytest_configure(config):config.addinivalue_line(markers, demo:demo标签名称)# 多个标签文件内容
def pytest_configure(config):marker_list [p0:p0级别用例, p1:p1级别用例, p2:p2级别用例] # 标签名称for markers in marker_list:config.addinivalue_line(markers, markers)
2. 项目中添加pytest.ini配置文件
[pytest]
markers p0:p0级别用例p1:p1级别用例p2:p2级别用例
使用方法
import pytestpytest.mark.p0
def test_mark01():print(函数级别的mark_p0)pytest.mark.p1
def test_mark02():print(函数级别的mark_p1)pytest.mark.P2
class TestDemo:def test_mark03(self):print(mark_p2)def test_mark04(self):print(mark_p2)
运行方式
1. 命令行运行
pytest -m p0 and p1
2. 文件运行
pytest.main([-m, P0, --htmlreport.html]) 内置标签
参数化pytest.mark.parametrize(argnames, argvalues)
无条件跳过用例pytest.mark.skip(reasonxxx)
有条件跳过用例pytest.mark.skipif(version 0.3, reason not supported until 0.3)
预测执行失败进行提示标记pytest.mark.xfail(version 0.3, reason not supported until 0.3)运行结果为X通过xpassed失败xfailed
# 参数化
import hashlibpytest.mark.parametrize(x, list(range(10)))
def test_somethins(x):time.sleep(1)pytest.mark.parametrize(passwd,[123456, abcdefgfs, as52345fasdf4])
def test_passwd_length(passwd):assert len(passwd) 8pytest.mark.parametrize(user, passwd,[(jack, abcdefgh),(tom, a123456a)])
def test_passwd_md5(user, passwd):db {jack: e8dc4081b13434b45189a720b77b6818,tom: 1702a132e769a623c1adb78353fc9503}assert hashlib.md5(passwd.encode()).hexdigest() db[user]# 如果觉得每组测试的默认参数显示不清晰可以使用 pytest.param 的 id 参数进行自定义
pytest.mark.parametrize(user, passwd,[pytest.param(jack, abcdefgh, id UserJack),pytest.param(tom, a123456a, id UserTom)])
def test_passwd_md5_id(user, passwd):db {jack: e8dc4081b13434b45189a720b77b6818,tom: 1702a132e769a623c1adb78353fc9503}assert hashlib.md5(passwd.encode()).hexdigest() db[user] Fixture
固件是一些函数pytest会在执行函数之前或者之后加载运行它们相当于预处理和后处理。
fixture的目的是提供一个固定基线在该基线上测试可以可靠地、重复的执行。
名称默认为定义时的函数名可以通过 pytest.fixture(namedemo) 给fixture重命名定义在固件函数定义前加上pytest.fixture()fixture是有返回值的没return则返回None使用作为参数、使用usefixtures、自动执行定义时指定autouse参数 def test_demo(fixture_func_name)pytest.mark.usefixtures(fixture_func_name1, fixture_func_name2) 标记函数或者类预处理和后处理用yield关键词yield之前的代码是预处理之后的是后处理作用域通过scope参数控制作用域 function函数级每个测试函数都会执行一次默认class类级别每个测试类执行一次所有方法都共享这个fixturemodule模块级别每个模块.py执行一次模块中所有测试函数、类方法 或者 其他fixture 都共享这个fixturesession会话级别每次会话只执行一次一次会话中所有的函数、方法都共享这个fixture集中管理使用文件conftest.py 集中管理在不同层级定义作用于在其所在的目录和子目录pytest会自动调用
scope、yield、auto的使用
# scope、yield、auto使用
pytest.fixture(scope function, autouseTrue)
def function_scope():passpytest.fixture(scope module, autouseTrue)
def module_scope():passpytest.fixture(scope session)
def session_scope():passpytest.fixture(scope class, autouseTrue)
def class_scope():passimport timeDATE_FORMAT %Y-%m-%d %H:%M:%Spytest.fixture(scopesession, autouseTrue)
def timer_session_scope():start time.time()print(\nsession start: {}.format(time.strftime(DATE_FORMAT, time.localtime(start))))yieldfinished time.time()print(\nsession finished: {}.format(time.strftime(DATE_FORMAT, time.localtime(finished))))print(session Total time cost: {:.3f}s.format(finished - start))def test_1():time.sleep(1)def test_2():time.sleep(2)
执行命令pytest --setup-show -s
固件执行结果
test_pytest_study.py
session start: 2020-04-16 17:29:02SETUP S timer_session_scopeSETUP M module_scopeSETUP C class_scopeSETUP F function_scopetest_pytest_study.py::test_3 (fixtures used: class_scope, function_scope, module_scope, timer_session_scope).TEARDOWN F function_scopeTEARDOWN C class_scopeSETUP C class_scopeSETUP F function_scopetest_pytest_study.py::test_4 (fixtures used: class_scope, function_scope, module_scope, timer_session_scope).TEARDOWN F function_scopeTEARDOWN C class_scopeTEARDOWN M module_scope
session finished: 2020-04-16 17:29:05
session Total time cost: 3.087sTEARDOWN S timer_session_scope
使用文件conftest.py 集中管理
# conftest.py
# condingutf-8
import pytestpytest.fixture()
def postcode():print(执行postcode fixture)return 010
# test_demo.py
# codingutf-8
import pytestclass TestDemo():def test_postcode(self, postcode):assert postcode 010if __name____main__:pytest.main([--setup-show, -s, test_demo.py])
python test_demo.py
执行过程
test_demo.py 执行postcode fixtureSETUP F postcodetest_demo.py::TestDemo::test_postcode (fixtures used: postcode).TEARDOWN F postcode
# 如果整个文件都用一个fixture可以用pytestmark标记
pytestmark pytest.mark.usefixtures(login)fixture参数化
固件参数化需要使用pytest内置的固件request并通过 request.param 获取参数。
# test_demo.py
pytest.fixture(params[(user1, passwd1),(user2, passwd2)])
def param(request):return request.parampytest.fixture(autouseTrue)
def login(param):print(\n登录成功 %s %s %param)yieldprint(\n退出成功 %s %s %param)def test_api():assert 1 1
pytest -s -v test_demo.py
运行结果
test_demo.py::test_api[param0]
登录成功 user1 passwd1
PASSED
退出成功 user1 passwd1test_demo.py::test_api[param1]
登录成功 user2 passwd2
PASSED
退出成功 user2 passwd2assert
assert h in hello
assert 34
assert 3!4
assert f()4
assert 56
assert not xx
assert {0, 1, 2} {0, 1, 2}
最后下方这份完整的软件测试视频学习教程已经整理上传完成朋友们如果需要可以自行免费领取 【保证100%免费】