进阶高级测试专项,Pytest自动化测试框架总结(四)

224 篇文章 12 订阅
25 篇文章 1 订阅


前言

1、pytest之不只是测试函数test_app能参数化,初始化函数before_test也能参数化

重点:测试用例的参数化+初始化清除函数的参数化  初始化清除函数的参数化能够实现appium的多终端测试

初始化清除函数的参数化,方法很多种:
before_test初始化函数注入参数,因为print(f’连接appium服务{port}')里面port需要变化的。

@pytest.fixture(scope=‘module’,params=[(4723,),(4727,)]):初始化清除函数的参数化

始化函数装饰器里面加params参数传参,port=request.param[0] 来调用params里的参数

#初始化清除函数的参数化:只传单个参数            import pytest
@pytest.fixture(scope='module',params=[(4723,),(4727,)])     #初始化清除函数的参数化params
def before_test(request):           
	port=request.param[0]               #param[0],假如注入多个参数一个port和一个data--需要params传元组,
												  #params=[(4723,100),(4727,200)],一个参数的话不需要写成列表嵌套元素,                                      #params[0]代表获取元组第一个
	print("启动被测app")
	print(f'连接appium服务{port}')
	yield   #后面写清除动作,
	after_test()
							  #request是pytest的对象,我们在用对象里面的方法的时候pycham不会自动帮我们取显示名字,                                      #它也不知道request里面到底什么内容
def after_test():
	print('关闭被测app')
	print('断开appium服务')

@pytest.mark.usefixtures('before_test')    
@pytest.mark.parametrize('psw',['boss123','boss456'])
def test_app(psw):                                   
	print('测试boss app')
	print(f'登录测试账号{psw}')

if __name__ == '__main__':
	pytest.main(['pytest_ywt.py','-s'])
#初始化清除函数的参数化:传多个参数                     import pytest
@pytest.fixture(scope='module',params=[(4723,'xiaomi'),(4727,'meizu')])  
def before_testquest):           
	port=request.param[0]          #param[0],假如注入多个参数一个port和一个data,需要params传元组,params=[(4723,100),(4727,200)],
									#一个参数的话不需要写成列表嵌套元素,request.params[0]代表获取元组第一个
	device=request.param[1]          #request.param[1]对应元素里面第二个参数,
	print(f"在{device}启动被测app")
	print(f'连接appium服务{port}')
	yield   #后面写清除动作,
	after_test()

						#request是pytest的对象,(固定写法:request.param)                                #我们在用对象里面的方法的时候pycham不会自动帮我们去显示名字,它也不知道request里面到底什么内容
def after_test():
	print('关闭被测app')
	print('断开appium服务')

@pytest.mark.usefixtures('before_test')                    
@pytest.mark.parametrize('psw',['boss123','boss456'])
def test_app(psw):           

	print('测试boss app')
	print(f'登录测试账号{psw}')

if __name__ == '__main__':
	pytest.main(['pytest_ywt.py','-s'])

2、pytest框架执行代码也能在cmd里面直接输入命令执行

xxx\test_case> pytest -s

在test_case这个目录执行会运行test_case文件里面所有的测试文件(test开头的测试用例)

3、分布式

设置用例每个模块独立,有什么前置做到模块里面,比如测试10个模块,用相关联来做,不能做分布式(并发执行)

每个模块独立还能定制执行那个模块,关联性太强做不到;
最好做到每个接口都独立化(前置条件做好)不要做太大关联性的接口;
每一层都能做环境清除和定制化(包,模块。类,函数)分层,为后面mark(定点执行哪些用例)和分布式打基础。

分布式:必须做到用例的隔离(低耦合,高内聚),用例走串行风险很大,很难维护

3000个请求,全部独立化,然后分布式来做(效率提高几倍–几十倍)

4、分布式的实现

分布式的核心点:封装设计:相互独立,登录和课程相互独立,至少模块为单元要相互独立,封装相互独立,接口用例之间最好也相互独立  才能进行分布式

一:pytest分布式环境搭建和理论介绍:

第一步:安装一个库pip install pytest-xdist分布式运行插件,可以做分布式(这个库有两种运行方式)

运行方式:
串行:顺序运行,串行运行,从头到尾
并行:pytest-xdist做分布式有两种,一种多核,一种多台机器

多核:单机多核来做(同时跑)使用-n参数
电脑多核有假有真:超线程技术(8内核搞成16核),真8核假8核—
cpu个数:硬件,几个cpu槽,i9900.i710–一般电脑就算一个cpu,单cpu,服务器可能有多个cpu
核数:电脑的核数。
逻辑核数:逻辑核数可以虚拟化,8核可以变成16核(超线程技术)

多核的话xdist本身的多核的话一般用逻辑核数来做的

多机(可以使用虚拟机)—需要搭环境,多台机器 很麻烦,装环境,下库

测试用例比较多怎么办:
分布式两种情况  
量大:多机 (需要文件报告收集还需要搭环境,做起来比较麻烦)
单机多核,很简单,加-n 参数就行 (做ui和需要一些时间等待的时候时间优化特别明显)

串行运行:本身是线程去跑的,python就一个进程,里面很多线程,走进程的话需要多台机器来做,分量, 用例设计不好会有大问题,数据不对(用例一定要独立化)

并行和多机:用例一定要设计好,不然数据容易出错,逻辑独立(不能有任何关联,不能有前后关系)  数据和代码封装时候独立化

分布式运行代码

#验证单机多核分布式
import pytest
import time

def test_01():
	time.sleep(3)
	print("-----test01-----")

def test_02():
	time.sleep(3)
	print("-----test01-----")


if __name__ == '__main__':
	# pytest.main(["test_xdist.py","-sq"])          #这是串行跑的   6s
	pytest.main(["test_xdist.py", "-sq","-n","8"])     #单机多核并行   加"-n","8" 参数  ,用8个核来跑,5.41s,时间少了
	#或者测试用例文件目录下 cmd,输入 pytest test_xdist.py -n 8  也可以    这样cmd里执行看到的结果更直观,
	#多核来跑在ui里面时间提升很大,ui里面很多地方需要sleep,等待元素(有等待的的提升比较大)多核跑更快
	#有等待的情况用多核跑效果越明显

串行运行本身按照线程去跑的,python本身就一个进程,里面很多线程
走进程的话,多台机器做比较合适—分量。

用例一定要设计好,不然数据容易出错,逻辑独立(不能有任何关联,不能有前后关系)----数据和代码封装时候独立化

pytest cmd执行多个模块用例:pytest test_xdist.py test_login.py -sq 运行两个.py文件(写多个运行多个)
pytest cmd执行多个包的用例:pytest test_xdist test_login -sq :运行test_xdist包和test_login 包
还可以运行不同模块的两个包,加包路径 case/test_xdist.py case2/test2_xdist.py

5、pytest的用例定制化执行mark标签

所有的接口不需要全部都跑(冒烟,定制化执行某些指定的业务,)“-m”,“test_lesson_add”

pytest框架mark标签,标记非常丰富,mark标签

mark标签:对于pytest,我们可以再每一个模块,每一个类,每一个方法和用例前面都加上mark,那样我们在pytest运行的时候就可以只运行带有该mark标签的模块,类,用例

这样的话可以方便我们选择执行自动化时,是执行全部用例,某个模块用例,某个流程用例,某个单独用例,总之就是可以某个单独的标签下所有用例

mark可以标记不同层次的东西(类,函数,方法都可以标记)文件不用标记(本身就可以定制化执行)

@pytest.mark.lessson_moudle 给测试类贴个标签,标签名字叫lessson_moudle标识课程模块,各个函数,类都可以贴上标签(类似别称),选择某个标签就运行某一个(灵活方便)

什么都不选中照常运行,(全部运行,没有限制)

mark标签pytest运行可能报错,PytestUnknownMarkWarning报错:是一个标签的mark警告,整个pytest这么写不识别你,但是不会报错,只是警告。
消除警告(增加标签栏,相当于标签的声明)

标签声明写法:teach_sq文件夹里创建一个pytest.ini的文件(pycham需要安装ini插件 file-setting-plugins(搜索ini)社区版似乎不行)

pycham找不到可以离线装

teach_sq
pytest.ini-----文件内容如下,相当于pytest的mark标签声明一下            #文件内容,markers后面把标签全部写上,    lessson_moudle   一个类级别的mark标签名,            #test_lesson_add,test_lesson_list,test_lesson_delete   三个函数级别的mark标签名称            #  mark标签名称: 描述   这样的格式来写,前面声明标签名称,后面是描述(随便写)
[pytest]                    
markers=
	lessson_moudle: teach_lesson	# (标签名: 描述  这样的格式前面lesson_modle和test_lesson_add等是mark的标签名称,声明一个标签:冒号后面一定要加空格,规范)                                  

后面的描述不建议写中文,会报错(需要转码,但是这个文件python自己调用的)
test_lesson_add: teach_lesson
test_lesson_list: teach_lesson
test_lesson_delete: teach_lesson

定制化执行test_lesson_add一个接口: “-m”,“test_lesson_add”

pytest.main([“test_lesson01.py”,“-s”,“-m”,“test_lesson_add”]) ---- -m就可以实现,mark定制化执行

定制化执行多个接口–逻辑或就行:“-m”,“test_lesson_add or test_lesson_delete”

pytest.main([“test_lesson01.py”,“-s”,“-m”,“test_lesson_add or test_lesson_delete”])

排除法排除一个-定制化除了某个接口不运行其他都运行—“-m”,“not test_lesson_add”

pytest.main([“test_lesson01.py”,“-s”,“-m”,“not test_lesson_add”])----除了test_lesson_add这个接口其他都运行

排除法排除多个-“-m”,“not (test_lesson_add or test_lesson_delete)”

pytest.main([“test_lesson01.py”,“-s”,“-m”,“not (test_lesson_add or test_lesson_delete)”])

筛选测试用例代码:

import pytest

@pytest.mark.zzzzz
def test_001():
    print('test_001')

def test_002():
    print('test_001')

if __name__ == '__main__':
    pytest.main(["test1.py",'-s','-m','zzzzz'])

定制化执行:(组装流程)

mark标签:组装流程方便
-k:匹配筛选用例名称(可标准(全名)可模糊匹配)—指的是模块,-k和-m类似,有or和not。

但是-k只运行所有的用例,然后有排除模式,选定模式,还要其他模式(-k在cmd里面写的)

pytest -k test_lesson01.py :执行test_lesson01.py模块的测试用例(sq可以不写,只是不加打印,sq错误执行的时候会有很多信息可以打印,)

全部选中,测试包里面的模块全部被选中:pytest -k test,(差不多功能的模块写同样单词命名,这样-k可以一起匹配上)

lesson_1.py 和lesson_2.py:想运行两个文件 pytest -k lesson (默认模糊匹配lesson)

-m: 选择对应的标签(标签,mark需要打标签才能定制化执行,其他两个k和v不用打标签)
-v:节点,你要运行里面的某一个某一个里面的东西:(节点指定某一个)

示例:

pytest_lesson.py::Test_lesson::test_01

pytest -v pytest_lesson.py::Test_lesson::test_01

-sq:(简化print打印信息)
-s:输出print打印
-q:简化输出
sq,错误时候显示错误信息,或者fail很多失败信息,很多打印的时候写sq打印(成功不用写)

跳过/条件跳过:通过上下条件判断这个东西要不要跑,(两种)skip

跳过(没有条件的跳过,指定跳过,不需要满足什么条件)skip

@pytest.mark.skip("跳过test_lesson_add") #无条件跳过

接口函数前面写@pytest.mark.skip(“跳过test_lesson_add”),
这个接口就会被无条件跳过,不执行(报告里面会描述出来)

有条件的跳过skip if

@pytest.mark.skipif(1==1,reason="条件需要前面完成某一个步骤--前面条件为真的时候则跳过函数,不为真执行函数") #有条件的跳过

流程化需要跳过接口,1,2,3,

1为真运行的时候才执行2,1不执行2也不执行,直接跳过)
条件从哪里来,预期和实际的做个判断(找个前置条件做个判断是不是为真)
如果登录失败那么课程接口就不要取跑了(可以这么写)登录失败没有sessionid

使用场景:前面一个动作失败了后面的不要跑了。
前置条件,或者检测到服务器python环境不是要求的,不要跑。
对版本有要求(系统环境,解释器版本都可以作为代码要不要执行的前置条件)
标签只能到接口(方法层),不能指定到用例,用例是通过数据驱动来做的

定制执行还有一种写法:
指名道姓----(下面的指令可以在cmd控制台命令里面直接执行)

只执行Test1的测试用例,执行命令:pytest -sq test_xt.py::Test1
py文件到类,类级别的(::级别关系)

只想执行Test2中test_3,执行命令:pytest -sq test_xt.py::Test2::test_3py文件,类,接口方法

同时执行多个条件:执行命令:pytest -sq test_xt.py::Test1::test01 test_xt.py::Test2::test02

也可以根据用例名称进行筛选-k,执行命令:pytest -sq -k 2 test_xt.py

下面是我整理的2023年最全的软件测试工程师学习知识架构体系图

一、Python编程入门到精通

请添加图片描述

二、接口自动化项目实战

请添加图片描述

三、Web自动化项目实战

请添加图片描述

四、App自动化项目实战

请添加图片描述

五、一线大厂简历

请添加图片描述

六、测试开发DevOps体系

请添加图片描述

七、常用自动化测试工具

请添加图片描述

八、JMeter性能测试

请添加图片描述

九、总结(尾部小惊喜)

永不止步,迎接挑战;心怀勇气,超越极限。勤奋与智慧铸就辉煌,激情与拼搏点亮未来。相信自己的能力与潜力,跨越困难,迈向成功的彼岸。

勇往直前,不畏艰辛;心怀信念,追逐梦想。奋斗的力量源于坚持与努力,每一次付出都将绽放成果的芬芳。相信自己的无限可能,拥抱挑战,创造属于自己的辉煌人生。不忘初心,砥砺前行,成功必将伴随着你!

无论遇到多少困难,坚持信念,不屈不挠。相信自己的能力与潜力,用汗水浇灌梦想的花朵。每一份努力都将累积力量,每一次奋斗都将迈向更高的巅峰。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值