找回密码
 会员注册
查看: 30|回复: 0

python篇-pytest框架详解

[复制链接]

5

主题

0

回帖

16

积分

新手上路

积分
16
发表于 2024-9-9 14:52:55 | 显示全部楼层 |阅读模式
Pytest框架1.简介pytest是纯python编写的自动化测试框架,可以支持python语法编写测试用例,是一个非常成熟的全功能的Python测试框架。主要有以下几个特点:简单灵活,容易上手;支持参数化;能够支持简单的单元测试和复杂的功能测试,还可以结合selenium、requests做自动化测试;pytest具有很多第三方插件,并且可以自定义扩展。安装:pipinstallpytest官方文档:https://docs.pytest.org2.创建第一个pytest用例deftest_01():assert1==13.pytest命名规范测试模块:以 test_ 开头命名,如:test_login.py,或以 _test 结尾;测试类:必须以Test开头命名,且测试类中不能有 __init__ 方法;测试方法/测试函数:必须以test开头。4.运行参数无参数:读取路径下符合条件的所有类、函数、方法全部执行;-v:打印详细运行日志;-s:打印print输出;-k:​跳过运行某个或某些用例pytest-k‘类名’pytest-k‘方法名’pytest-k‘类名andnot方法名’#运行类里所有方法,不包含某个方法-x:运行用例失败立即停止运行–maxfail用例失败数达到某个设定的值停止运行pytest--maxfail=[num]-m运行所有@pytest.mark.[标记名]标记的用例5.pytest实现数据驱动 pytest.mark.parametrize()Pytest测试框架的数据驱动是由pytest自带的pytest.mark.parametrize()来实现的。@pytest.mark.parametrize()装饰器接收两个参数:第一个参数以字符串的形式存在,它代表能被测试函数所能接受的参数,如果被测试函数有多个参数,则以逗号分隔;第二个参数用于保存测试数据。如果只有一组数据,以列表的形式存在,如果有多组数据,以列表嵌套元组的形式存在(例如:[1,1]或者[(1,1),(2,2)])。实例classTest01pytest.mark.parametrize('a,b,expect',[(1,1,1),(2,3,5)])deftest_001(self,a,b,expect):print('测试a+b的结果')asserta+b==expect@pytest.mark.parametrize('c,d,expect',[(2,4,2),(9,10,1)])deftest_002(self,c,d,expect):assertd-c==expectif__name__=='__main__':pytest.main([__file__,'-k','test_001'])6.pytestfixtures6.1fixture用途fixture主要用来做初始化环境以及测试结束后的数据清除。pytestfixture与setup,teardown功能一样,但比之更加灵活,完全可以代替setup,teardown。 6.2fixture参数详解@pytest.fixture(scope='function',params=None,autouse=False,ids=None,name=None)yieldfixture装饰器,相当于setup,测试用例的前置*scope:有四个级别参数'function(默认)'、'class'、'module'、'session'。*params:一个可选的参数列表,列表中每个数据都可以作为用例的输入。也就说有多少数据,就会形成多少用例。可以通过request.param来获取该次调用的参数。*autouse:如果True,自动调用fixture功能。如果为False则需要调用fixture。*ids:每个字符串id的列表,每个字符串对应于params这样他们就是测试ID的一部分。如果没有提供ID它们将从params自动生成。*name:fixture的名称。这默认为装饰函数的名称。如果fixture在定义它的统一模块。yield:这个关键字之后的代码相当于teardown,测试用例的后置。6.3fixture的作用范围fixture里面有个scope参数可以控制fixture的作用范围:session>module>class>function-function:每一个函数或方法都会调用-class:每一个类调用一次,一个类中可以有多个方法-module:每一个.py文件调用一次,该文件内又有多个function和class-session:是多个文件调用一次,可以跨.py文件调用,每个.py文件就是module6.4调用fixture的三种方法 方式1:函数或类里直接传fixture的函数名称 @pytest.fixture()deftest_fixture(self):print('\n用例开始执行fix1\n')yieldprint('\n用例执行结束fix1\n')deftest_a(self,test_fixture):print('runing')assert1==1执行结果: 方式2:使用装饰器@pytest.mark.usefixtures()修饰需要运行的用例(可以叠加使用多个装饰器)@pytest.fixture()deftest_fixture(self):print('\n用例开始执行fix1\n')yieldprint('\n用例执行结束fix1\n')@pytest.fixture()deftest_fixture2(self):print('\n用例开始执行fix2\n')yieldprint('\n用例执行结束fix2\n')@pytest.mark.usefixtures('test_fixture')@pytest.mark.usefixtures('test_fixture2')deftest_b(self):assert1==1执行结果7.skip–跳过测试 7.1pytest.skip()用于函数内,跳过测试用例@pytest.mark.parametrize('a,b,expect',[(1,1,1),(2,3,5)])deftest_001(self,test1,a,b,expect):pytest.skip('跳过此测试用例')asserta+b==expect用于函数外,跳过测试用例@pytest.mark.skip(reason="功能未实现")@pytest.mark.parametrize('a,b,expect',[(1,1,1),(2,3,5)])deftest_001(self,test1,a,b,expect):asserta+b==expect 用在函数外,条件condition为True时,跳过用例@pytest.mark.skipif(condition=True,reason="功能未实现")@pytest.mark.parametrize('a,b,expect',[(1,1,1),(2,3,5)])deftest_001(self,test1,a,b,expect):asserta+b==expect8.rerunfailure–失败重跑,插件pytest-rerunfailures安装前提条件: pytest(>=5.3) 和python>=3.6安装:pipinstallpytest-rerunfailures查看安装版本:pipshowpytest-rerunfailurespytest-rerunfailures使用命令行参数:--rerunsn(重新运行次数)–reruns-delaym(等待运行秒数)使用装饰器:@pytest.mark.flaky(reruns=5,reruns_delay=2)命令行实例#!/usr/bin/envpython3#!coding:utf-8importpytestimportrandomdeftest_simple_assume():#每次case运行的值为1或者2,具有随机性r=random.randint(1,3)assertr==1if__name__=='__main__':pytest.main(['Test_demo01.py','-v','--reruns=2','--reruns-delay2'])配置执行次数越多(如--reruns=2),执行的成功率越高。命令行参数:--rerunsn(重新运行次数),--reruns-delaym(等待运行秒数)例如pytestpytest-demo.py--reruns3 --reruns-delay2装饰器实例@pytest.mark.flaky(reruns=5,reruns_delay=2)deftest_01(self):print('---用例01---')assert1==2 执行结果9.Mark装饰器之order–执行顺序需要先安装插件cmd命令窗口:pipinstallpytest-ordering在pycharm中File-->settings-->roject-->ythonInterpreter-->点击+号-->搜索pytest-ordering安装。查看安装版本:pipshowpytest-ordering使用方法:控制用例执行顺序的方法;在需要调整用例执行顺序的函数(或方法)前增加,如@pytest.mark.run(order=x),x表示数字;执行顺序,由小到大、由正到负、未标记的在正数后、负数前执行,顺序为:1,2,3,无标记,-3,-2,-1;实例importpytestclassTest_Class3()pytest.mark.run(order=2)deftest_case1(self):print("测试方法1")@pytest.mark.run(order=1)deftest_case2(self):print("测试方法2")@pytest.mark.run(order=3)deftest_case3(self):print("测试方法3")if__name__=='__main__':pytest.main(['Test_demo02.py''-s'])执行结果=============================testsessionstarts=============================collecting...collected3itemsTest_demo02.py::Test_Class3::test_case2PASSED[33%]测试方法2Test_demo02.py::Test_Class3::test_case1PASSED[66%]测试方法1Test_demo02.py::Test_Class3::test_case3PASSED[100%]测试方法3==============================3passedin0.02s==============================10、setup、teardown,pytest方法名setup_class()和teardown_class()函数需要定义在测试类中,定义在类外不起作用。setup_class()定义场景,比如:创建日志对象,创建数据库的连接,创建接口的请求对象等。teardown_class()定义场景,比如:销毁日志对象,销毁数据库的连接,销毁接口的请求对象。"""函数需要定义在测试类中,定义在类外不起作用。setup_method()和teardown_method(),在每个测试方法之前/之后执行。定义场景,比如:打开浏览器/关闭浏览器。setup_class()定义场景,比如:创建日志对象,创建数据库的连接,创建接口的请求对象等。teardown_class()定义场景,比如:销毁日志对象,销毁数据库的连接,销毁接口的请求对象。"""importpytestclassTest_setUp_tearDown:#方法级,前置函数defsetup_method(self):#print("setup_method(self):在每个测试方法之前执行")print("在每个测试方法之前执行")#方法级,后置函数defteardown_method(self):#print("teardown_method(self):在每个测试方法之后执行\n")print("在每个测试方法之后执行")#类级,前置函数defsetup_class(self):#print("setup_class(self):每个测试类之前执行一次\n")print("每个测试类之前执行一次")#类级,后置函数defteardown_class(self):#print("teardown_class(self):每个测试类之后执行一次")print("每个测试类之后执行一次")#测试用例adeftest_a(self):print("test_a方法")assertTrue#测试用例bdeftest_b(self):print("test_b方法")assertTrueif__name__=='__main__':pytest.main()11、问题:pytest执行的case,如果返回结果有中文,获取数据显示unicode编码格式原因:是pytest默认将输出报告视为ASCII字符串,并在测试报告中按原样显示。由于中文字符不属于ASCII字符范围,因此pytest会将其转换为Unicode编码表示。解码后,pytest的执行报告才能正常显示中文。使用语句:result=response.content.decode("unicode-escape")参考文档:pytest框架详解_pytest框架cllections.abc-CSDN博客
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-10 06:01 , Processed in 0.439852 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表