def test_02(self):
print(“第二条测试用例”)
def test_03(self):
print(“第三条用例”)
pytest running.py -vs - n 2 --reruns 2,看下方的截图,重复运行的两次。
测试报告
pytest框架自带了一个测试报告生成器。–html=路径/名称.html
def test_01():
print(“第一条用例”)
assert 0>1
def test_04():
print(“清安无别事”)
class Testcase:
def test_02(self):
print(“第二条测试用例”)
def test_03(self):
print(“第三条用例”)
如果我想将这四个用例生成测试报告:
pytest running.py -vs - n 2 --reruns 2 --html=report/report.html
在report文件夹下生成一个report.html报告,这个报告虽然很一般 ,也是不错了。当然我们也可以生成allure测试报告,美观一些。
allure
======
pip install allure-pytest下载好库。
pytest running.py -vs --alluredir …/report/xmll
allure generate --clean …/report/xmll -o ./result/html
仔细看你就会发现其实–clean后面接的是运行代码时-o后面的路径,因为运行pytest running.py -vs --alluredir …/report/xmll后,文件下会自行创建一个report文件,用例运行信息会存在xmll里面,我们生成报告就需要调用里面的信息。
因为我是控制台输出的所以需要这两行代码,输出完后就可以在result文件下看到一个index.html文件,就是测试报告了。如下图所示:
mark标签
======
什么是mark标签?mark标签分为内置标签与外置标签,可以用来对用例进行管理运行,我们直接看看例子:
def test002():
print(‘这是一条最优级别的用例’)
def test005():
print(“skip_reason”)
def test003():
print(‘这是一条严重级别的用例’)
def test006():
print(“006冒烟”)
def test004():
print(‘这是一条较严重级别的用例’)
上述例子的情况下,与正常情况下无异,这里需要注意:
pytest与unittest不一样,我test序列号写的很乱,如果是在unittest中的话肯定就是按数字的顺序来执行了,pytest中不分先后,05在04用例的前面,那么就得按这顺序来,先运行05用例再04用例。
那么我们给这里加上mark标签看看:
def test002():
print(‘这是一条最优级别的用例’)
def test005():
print(“005冒烟”)
@pytest.mark.qingan
def test003():
print(‘这是一条严重级别的用例’)
def test006():
print(“006冒烟”)
@pytest.mark.qinganan
def test004():
print(‘这是一条较严重级别的用例’)
猜猜这里运行几条用例?3条,没错。
注意:这里mark标签是外置标签,我自己命名的。看看运行结果:
pytest -m qingan test_speack.py -sv这里指定外置标签的标签名。不指定就会运行全部的用例,不指定怎么对用例进行管理。
这里还是可以看到只执行了两条,也就是标签的那两条用例。这里对指定用例进行标记运行。
mark标签会受外界的装饰器影响吗?我们来看看。
def func(function):
def fn(*args,**kwargs):
print("this is "+function.name)
return function(*args,**kwargs)
return fn
----------上面是自己写的装饰器--------------
@func
def test002():
print(‘这是一条最优级别的用例’)
@pytest.mark.skip
def test005():
print(“skip_reason”)
@pytest.mark.qingan
@func
def test003():
print(‘这是一条严重级别的用例’)
def test006():
print(“006冒烟”)
@pytest.mark.qingan
@func
def test004():
print(‘这是一条较严重级别的用例’)
是不会的,也是遵循pytest强大的执行顺序来的。
那么看了自定义标签,看看内置标签吧:
def func(function):
def fn(*args,**kwargs):
print("this is "+function.name)
return function(*args,**kwargs)
return fn
----------上面是自己写的装饰器--------------
@func
def test002():
print(‘这是一条最优级别的用例’)
@pytest.mark.skip
def test005():
print(“skip_reason”)
@pytest.mark.qingan
@func
def test003():
print(‘这是一条严重级别的用例’)
def test006():
print(“006冒烟”)
@pytest.mark.qingan
@func
def test004():
print(‘这是一条较严重级别的用例’)
我在05用例处添加了一个内置标签,这里需要注意的是,执行命令不一样:
pytest test_speack.py -s -rs或者pytest -k qingan test_speack.py -sv
05被跳过了,我们可以更改内置标签的提示信息
@pytest.mark.skip(reason=‘不运行’)
def test005():
print(“skip_reason”)
控制台就会有这样的一条信息可以看到。
这里可以看到自定义标签与内置标签处用的运行命令有所不同,不同之处在于一个用了-m一个用了-k。
使用-m的时候我们需要指定自定义标签,才能跑用例,否则跑不起来,如果用-k即使不指定也是可以跑起来,这样的一个好处,相信不说你也知道了,控制用例执行,可以更好的执行你想执行的用例。更好的是用于冒烟测试。
另外还有一个也就是内置标签判断,skipif。这是一个怎么样的标签呢?
看skip后面带的if就知道了,可以做一个判断!条件为真则跳过运行,条件为假则运行用例。
@func
def test002():
print(‘这是一条最优级别的用例’)
@pytest.mark.skipif(1>2,reason=‘不运行’)
def test005():
print(“skip_reason”)
@pytest.mark.qingan
@func
def test003():
print(‘这是一条严重级别的用例’)
def test006():
print(“006冒烟”)
@pytest.mark.qingan
@func
def test004():
print(‘这是一条较严重级别的用例’)
pytest -k test_speack.py -sv我在用例005处写了一个skipif的判断,1>2是FALSE,所以此处不跳过。
所以此处为真的条件就不举例了,此处直接告诉各位答案了。
前置后置
====
在unittest你肯定看到过setup这一类的函数,看下面的例子
class Testcasse():
“”“前置后置”“”
def setup(self):
print(“1每个用例的前置”)
def teardown(self):
print(“2每个用例的后置”)
def setup_class(self):
print(“3所有用例的前置”)
def teardown_class(self):
print(“4所有用例的后置”)
def test_004(self):
print(“004”)
def test_005(self):
print(“005”)
其中的顺序是怎么样的呢。是否跟之前说的全部无优先级呢?运行一下就知道了。
这里就很明显了,优先级是3124,这里别误会,我在print里面加了数字,说一 这里就这样简写了。下面两个用例004,005是用于分辨的,不然运行不起来。各位可以自己跑一跑。这与pytest本身的规则有关系。
fixture
=======
这里很容易弄错写成fixtrue,所以需要注意一些。怎么用呢?fixture可以实现我们在pytest的用例中调佣其他函数,可以发现我们使用fixture是在被调用函数之上添加我们的fixture。看例子:
@pytest.fixture
def login():
print(“login”)
return “运行用例”
def test_seacher():
print(login) # 返回的是一个地址
print(f"搜索用户名{login}")
def test_seacher1(login):
print(login)
print(f"搜索用户名{login}")
pytest text_fixtrue.py -sv运行起来看看效果:
这样看就不难理解了。这是一种简单的距离,看起来像是调用。
fixture区别于unnitest的传统单元测试(setup/teardown)有显著改进。
fixture里面有个scope参数可以控制fixture的作用范围:session>module>class>function
-function:每一个函数或方法都会调用
-class:每一个类调用一次,一个类中可以有多个方法
-module:每一个.py文件调用一次,该文件内又有多个function和class
-session:是多个文件调用一次,可以跨.py文件调用,每个.py文件就是module
这里就需要用到了conftest.py配置了。可以实现数据共享,比如py跨文件共享前置,另外需要注意的是conftest.py脚本名称是固定的,不更改名称。pytest会自动寻找这个文件。
如果此文件放到项目的根目录下就可以全局调用了,如果放到某个package下,那就在改package内有效。
在根目录下这是conftest下的内容:
@pytest.fixture(scope=‘function’)
def openbrowser():
print(“打开浏览器”)
@pytest.fixture(scope=‘session’)
def qingan():
print(“我是清安”)
这是某个文件内的demo下的内容,主要看Testcase中的内容:
@pytest.fixture(scope=‘session’)
def login():
print(“登录方法”)
return “浏览器”
此处当scope等于function时,yield可以作用于全局
yield “类似于teardown,用法可以跟return一样”
def testSQL(login):
print(“链接数据库”)
print(login)
return “数据库连接结果”
@pytest.fixture()
def test01(login):
print(“用例1”)
class Testcase():
def test02(self,openbrowser):
print(“用例2”)
def test03(self,qingan):
print(“用例3”)
我调用了conftest下的function跟session参数方法。
这里可以看到,都被调用了。当然方法不唯一,用法不唯一,这里做这么一个简单的介绍,主要看各位怎么个用法。module也可以这样写。
接下来我们来看看实际的示例,我打开浏览器:demo.py文件
from selenium import webdriver
这里每次都需要打开一次浏览器,然后关闭再打开
@pytest.fixture
def fox():
fox1 = webdriver.Firefox()
print(“login”)
return fox1
def test_seacher(fox):
fox.get(“https://baidu.com”)
fox.quit()
def test_seacher1(fox):
fox.find_element_by_id(‘kw’).send_keys(“pytest”)
fox.find_element_by_id(‘su’).click()
fox.quit()
这里是单独的fixture直接同一文件下调用。打开两开浏览器,有点像unittest中的setup用法。这里的test_seacher1`又再次打开了一次浏览器导致不是百度界面无法定位到元素。
那么我们看看session怎么用------conftest.py文件
import pytest
from selenium import webdriver
@pytest.fixture(scope=‘session’)
def fox():
fox = webdriver.Firefox()
yield fox
demo.py文件
@pytest.mark.usefixtures(‘fox’)
class TestCase():
def test01(self,fox):
fox.get(“https://baidu.com”)
print(fox.title)
def test02(self,fox):
fox.find_element_by_id(‘kw’).send_keys(“pytest”)
fox.find_element_by_id(‘su’).click()
def test03(self,fox):
fox.quit()
这里用到了mark标签中的usefixtures方法,不用解释应该也知道了有use的地方是什么意思了吧,使用fixture方法,这里直接引入了conftest中的fox,只打开一次浏览器就能往下定位了。是不是很神奇。当然,module也是用在conftest里面。
参数化
===
有点像数据驱动,可以处理一些测试数据,简单的看看它的一个格式情况:
argnames:参数名
argvalues:参数对应值,类型必须为list
datas = [(‘qingan’, ‘123’),(‘qingqingan’, ‘123456’)]
class TestQingan:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数软件测试工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年软件测试全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上软件测试开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注软件测试)
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
, ‘123’),(‘qingqingan’, ‘123456’)]
class TestQingan:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数软件测试工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年软件测试全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-pVQMAhYI-1713035501723)]
[外链图片转存中…(img-fJvE0Dbw-1713035501724)]
[外链图片转存中…(img-JXTmQwWb-1713035501724)]
[外链图片转存中…(img-4Vqb31QW-1713035501725)]
[外链图片转存中…(img-jjDxbRSj-1713035501725)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上软件测试开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注软件测试)
[外链图片转存中…(img-RHA7S6OX-1713035501726)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!