全网最全pytest大型攻略,单元测试学这就够了
pytest是一款以python为开发语言的第三方测试,主要特点如下:比自带的unittest更简洁高效,兼容unittest框架支持参数化可以更精确的控制要测试的测试用例丰富的插件,已有300多个各种各样的插件,也可自定义扩展,如pytestselenium、pytesthtml、pytestrerunfailures、pytesxdish可很好的和CI工具结合安装
pipinstallpytest
测试用例编写规则测试文件以test开头或者test结尾测试类以Test开头,并且不能带有init方法测试文件以test开头断言使用基本的assert即可
pytest会递归查找当前目录及子目录下所有以test开始或者test结尾的python脚本,执行其中符合规则的函数和方法,不需要显示调用
运行命令:(cmd进入用例所在目录)pytestfoldername》直接运行文件夹内符合规则的所有用例
pytesttestfile。py》执行某个py文件中的用例
pytesttestfile。py::testfunc》执行模块内的某个函数(节点运行)
pytesttestfile。py::TestClass::testmethod》执行模块内测试类的某个方法(节点运行)
pytesttestfile。py::TestClass》执行模块内某个测试类(节点运行)
pytesttestfile。py::TestClasstestfile2。py::testmothod》多节点运行,中间用空格隔开
pytestkpass》匹配用例名称的表达式,含有pass的被执行,其他的deselected
pytestkpassorfail》组合匹配,含有pass和fail的被执行
pytestknotpass》排除运行,不含pass的被执行
pytestmfinished》标记表达式,运行用pytest。mark。finished标记的用例
pytestmfinishedandnotmerged》多个标记逻辑匹配,运行含有finished不含merged标记的用例
pytestv》运行时显示详细信息
pytests》显示打印消息
pytestx》遇到错误就停止运行
pytestxmaxfail2》遇到两个错误就停止运行
pytestsetupshow》跟踪固件运行
pytestvreruns5rerunsdelay1》运行失败的用例间隔1s重新运行5次pipinstallpytestrerunfailures
pytest》多条断言,报错后,后面的依然执行,pipinstallpytestassume,断言pytest。assume(24)
pytestn3》3个cpu并行执行测试用例,需保证测试用例可随机执行,pipinstallpytestxdist分布式执行插件,多个cpu或主机执行
pytestvnauto》自动侦测系统里cpu的数目
pytestcount2》重复运行测试pipinstallpytestrepeat
pytesthtml。reportreport。html》生成报告,此报告中css是独立的,分享时会丢失样式,pipinstallpytesthtml
pytesthtmlreport。htmlselfcontaindhtml》合并css到html报告中,除了passed所有行都被展开
pytestdurations10》获取最慢的10个用例的执行耗时
用例执行顺序控制
pytest用例执行顺序默认是按字母顺序去执行,要控制执行顺序,需要安装插件pytestordering:pipinstallpytestordering
在测试方法上加上装饰器:
pytest。mark。last最后一个执行
pytest。mark。run(ordern)n1则是第一个执行
Mark
标签的使用方法:
注册标签名内置标签在测试用例测试类模块文件前面加上pytest。mark。标签名
注册方法:
1。在conftest。py文件中添加代码单个标签文件内容
defpytestconfigure(config):
config。addinivalueline(markers,demo:demo标签名称)
多个标签文件内容
defpytestconfigure(config):
markerlist〔p0:p0级别用例,p1:p1级别用例,p2:p2级别用例〕标签名称
formarkersinmarkerlist:
config。addinivalueline(markers,markers)
2。项目中添加pytest。ini配置文件〔pytest〕
markers
p0:p0级别用例
p1:p1级别用例
p2:p2级别用例
使用方法:importpytest
pytest。mark。p0
deftestmark01():
print(函数级别的markp0)
pytest。mark。p1
deftestmark02():
print(函数级别的markp1)
pytest。mark。P2
classTestDemo:
deftestmark03(self):
print(markp2)
deftestmark04(self):
print(markp2)
运行方式:
命令行运行
pytestmp0andp1
文件运行
pytest。main(〔m,P0,htmlreport。html〕)
内置标签:
参数化:pytest。mark。parametrize(argnames,argvalues)
无条件跳过用例:pytest。mark。skip(reasonxxx)
有条件跳过用例:pytest。mark。skipif(version0。3,reasonnotsupporteduntil0。3)
预测执行失败进行提示标记:pytest。mark。xfail(version0。3,reasonnotsupporteduntil0。3),运行结果为X(通过xpassed,失败xfailed)参数化
importhashlib
pytest。mark。parametrize(x,list(range(10)))
deftestsomethins(x):
time。sleep(1)
pytest。mark。parametrize(passwd,〔123456,abcdefgfs,as52345fasdf4〕)
deftestpasswdlength(passwd):
assertlen(passwd)8
pytest。mark。parametrize(user,passwd,〔(jack,abcdefgh),(tom,a123456a)〕)
deftestpasswdmd5(user,passwd):
db{
jack:e8dc4081b13434b45189a720b77b6818,
tom:1702a132e769a623c1adb78353fc9503
}
asserthashlib。md5(passwd。encode())。hexdigest()db〔user〕
如果觉得每组测试的默认参数显示不清晰,可以使用pytest。param的id参数进行自定义
pytest。mark。parametrize(user,passwd,
〔pytest。param(jack,abcdefgh,idUser),
pytest。param(tom,a123456a,idUser)〕)
deftestpasswdmd5id(user,passwd):
db{
jack:e8dc4081b13434b45189a720b77b6818,
tom:1702a132e769a623c1adb78353fc9503
}
asserthashlib。md5(passwd。encode())。hexdigest()db〔user〕
Fixture
固件:是一些函数,pytest会在执行函数之前或者之后加载运行它们,相当于预处理和后处理。
fixture的目的是提供一个固定基线,在该基线上测试可以可靠地、重复的执行。名称:默认为定义时的函数名,可以通过pytest。fixture(namedemo)给fixture重命名
定义:在固件函数定义前加上pytest。fixture();fixture是有返回值的,没return则返回None
使用:作为参数、使用usefixtures、自动执行(定义时指定autouse参数)
deftestdemo(fixturefuncname)
pytest。mark。usefixtures(fixturefuncname1,fixturefuncname2)标记函数或者类
预处理和后处理:用yield关键词,yield之前的代码是预处理,之后的是后处理
作用域:通过scope参数控制作用域
function:函数级,每个测试函数都会执行一次(默认)
class:类级别,每个测试类执行一次,所有方法都共享这个fixture
module:模块级别,每个模块。py执行一次,模块中所有测试函数、类方法或者其他fixture都共享这个fixture
session:会话级别,每次会话只执行一次,一次会话中所有的函数、方法都共享这个fixture
集中管理:使用文件conftest。py集中管理,在不同层级定义,作用于在其所在的目录和子目录,pytest会自动调用
scope、yield、auto的使用scope、yield、auto使用
pytest。fixture(scopefunction,autouseTrue)
deffunctionscope():
pass
pytest。fixture(scopemodule,autouseTrue)
defmodulescope():
pass
pytest。fixture(scopesession)
defsessionscope():
pass
pytest。fixture(scopeclass,autouseTrue)
defclassscope():
pass
importtime
DATEFORMATYmdH:M:S
pytest。fixture(scopesession,autouseTrue)
deftimersessionscope():
starttime。time()
print(sessionstart:{}。format(time。strftime(DATEFORMAT,time。localtime(start))))
yield
finishedtime。time()
print(sessionfinished:{}。format(time。strftime(DATEFORMAT,time。localtime(finished))))
print(sessionTotaltimecost:{:。3f}s。format(finishedstart))
deftest1():
time。sleep(1)
deftest2():
time。sleep(2)
执行命令:pytestsetupshows
固件执行结果:
testpyteststudy。py
sessionstart:2020041617:29:02
SETUPStimersessionscope
SETUPMmodulescope
SETUPCclassscope
SETUPFfunctionscope
testpyteststudy。py::test3(fixturesused:classscope,functionscope,modulescope,timersessionscope)。
TEARDOWNFfunctionscope
TEARDOWNCclassscope
SETUPCclassscope
SETUPFfunctionscope
testpyteststudy。py::test4(fixturesused:classscope,functionscope,modulescope,timersessionscope)。
TEARDOWNFfunctionscope
TEARDOWNCclassscope
TEARDOWNMmodulescope
sessionfinished:2020041617:29:05
sessionTotaltimecost:3。087s
TEARDOWNStimersessionscope
使用文件conftest。py集中管理conftest。py
condingutf8
importpytest
pytest。fixture()
defpostcode():
print(执行postcodefixture)
return010
testdemo。py
codingutf8
importpytest
classTestDemo():
deftestpostcode(self,postcode):
assertpostcode010
ifnamemain:
pytest。main(〔setupshow,s,testdemo。py〕)
pythontestdemo。py
执行过程:
testdemo。py执行postcodefixture
SETUPFpostcode
testdemo。py::TestDemo::testpostcode(fixturesused:postcode)。
TEARDOWNFpostcode
如果整个文件都用一个fixture,可以用pytestmark标记
pytestmarkpytest。mark。usefixtures(login)
fixture参数化
固件参数化需要使用pytest内置的固件request,并通过request。param获取参数。testdemo。py
pytest。fixture(params〔
(user1,passwd1),
(user2,passwd2)
〕)
defparam(request):
returnrequest。param
pytest。fixture(autouseTrue)
deflogin(param):
print(登录成功ssparam)
yield
print(退出成功ssparam)
deftestapi():
assert11
pytestsvtestdemo。py
运行结果:
testdemo。py::testapi〔param0〕
登录成功user1passwd1
PASSED
退出成功user1passwd1
testdemo。py::testapi〔param1〕
登录成功user2passwd2
PASSED
退出成功user2passwd2
assertasserthinhello
assert34
assert3!4
assertf()4
assert56
assertnotxx
assert{0,1,2}{0,1,2}
满城绽放!它一开,就是济南春天的顶流!摄影:陈振又是一年三月,玉兰花挂满了枝头,走在街头,风中都是玉兰香甜的气息,若是到了夜晚,漫步在花影绰绰的小路上,那便像是找回了初恋般的感觉。在济南,不少地方的玉兰……
唐僧的头盖骨揭秘大报恩寺地宫里最值钱的宝物大报恩寺位于江苏南京中华门外雨花路东侧秦淮河畔长干里。传说是明朝永乐皇帝朱棣为纪念其生母,在1412年到1431年期间兴建的一组规模庞大,有如宫殿般金碧辉煌的建筑群。其中有一座……
令人作呕的大象水下表演!在泰国曼谷东南部的KhaoKheow动物园。一头小象,在驯兽师的恐吓下,将头部和身体都浸在水下,游客们正在玻璃水箱外,观看并拍摄它的表演。在这种表演形式背后,是从小被迫与母亲分……
汽车自动驾驶芯片行业研究(报告出品方作者:海通国际,郑宏达,华晋书)核心观点:1。自动驾驶与智能座舱芯片一体化趋势明显,自动驾驶芯片具有高算力发展趋势。市场容量未来5年将会高速增长。2。目前自动……
股市风险高,专家不建议普通人下场炒股随着股市的不断升温,越来越多的人开始关注股票市场,并考虑参与其中。然而,近日有多位专家表示,股市风险高,不建议普通人下场炒股,这一消息引发了广泛关注和讨论。股市的风险性一……
一加Ace2V已发货?酷安网友预定分享,李杰预售数据非常惊人从2月份开始,新机就一部接一部地发布,在20003000元价位段,刚刚发布的一加Ace2V无疑是最亮眼的存在,虽然目前尚未正式开售,但一加中国区总裁李杰表示:这个产品受大家喜爱……
义新欧班列为中西贸易提速近年来,以义新欧班列为代表的中欧班列,为中西经贸合作注入了源源动力。图为三月九日从西班牙马德里向中国义乌发出的中西建交纪念号中欧班列。本报记者颜欢摄3月9日,伴随着……
联名还得看麦当劳,拿下女团NEWjeans之后,又跟陈冠希有出道还没一年的NEWjeans,就已经火到被称为怪物新人女团,她们古灵精怪的y2k造型,校园少女感满满,只要看到她们就会收获一大波快乐。每次看到她们的发型、服装、妆容都会被惊艳……
原来蛋糕可以美的像画一样这不就是画吗?原来蛋糕可以美的像画一样这不就是画吗?蛋糕是一道美食,在生日的时候是一个象征性蛋糕相信也是甜品爱好者的心头好大部分的人都拒绝不了这一份美味的诱惑这小小一块蛋糕……
观汉中锦绣油菜花海,品天汉特色传统小吃每年3月至4月下旬,汉中(古雅称天汉)将是一片油菜花的海洋。2023中国最美油菜花海汉中旅游文化节活动启动仪式已在汉中市南郑区阳春镇陈村举行。此时的汉中盆地和浅山丘陵的百万亩油……
天文学家发现超大黑洞,质量是太阳的300亿倍!英国天文学家使用新技术发现了一个超大质量黑洞,是迄今为止被发现的最大黑洞之一。皇家天文学会发表的研究结果表明,这个黑洞的质量是太阳质量的300多亿倍。研究人员将其描述为一……
AI4S,最新的第五范式来了!上海推进智能化科学设施,建设无最新的第五范式来了。日前,为了贯彻落实国家《新一代人工智能发展规划》,科技部会同国家自然科学基金委启动人工智能驱动的科学研究(AIforScience)专项部署。AIforSc……