pytest

初识pytest

1.认识:

pytest是一个第三方的单元测试框架;不仅可以用于单元测试,还可以用于接口,GUI自动化测试,而且可以很好的和CI(持续集成)结合使用;

2.特征:

  • 简单灵活,容易上手,对初识者很友好;
  • 支持参数化,可以细粒度掌控测试的测试用例;
  • 能够支持简单的单元测试和复杂的功能测试,还可以结合selenium/appium做GUI自动化测试,接口自动化测试(pytest+requests)
  • pytest 具有很多第三方插件,并且可以自定义扩展(之前我以为是像浏览器上的一些插件,没想到就是python的第三方库),例如
  • pytest-selenium:集成selenium
  • pytest-html:html 测试报告生成
  • pytest-rerunfailures:失败重复执行
  • pytest-xdist:多CPUA分发:(这里指的是多进程;多进程效率高,但是特别消耗计算机资源(磁盘,CPU、内存、电量等等),相反:多线程:相比较多进程效率不是很高,但不是很消耗计算机资源,)
  • 可以很好的和CI(持续集成)工具(jenkins)结合

使用规范

1.以模块维度来收集测试用例,必须以test 开头或者 --test结尾;
2.类名必须以大写Test 开头,且不能有构造方法;
3.函数名、方法名也必须以test开头;
4.断言时,必须使用python自带的关键字 assert

assert bool 表达式

参数

-s: 指的输出打印结果,一般默认是不打印的
-v: 指的是详细的日志信息
-q:极简模式(指的是呈现非常的简洁,简单的方式呈现)
-x: 指的是 出现错误的时候,停止运行;
-maxfail=n: 指的是当测试用例出现n条错误的时候,则停止运行;
-k: 关键字或者逻辑运算符 :只执行模块名、类名、方法名、函数名中包含指定关键字的测试;

pystest.main(['-k func or method'])  #只执行方法名中带有func或者method这个关键字的测试方法

-m ,执行指定标记的用例
第一步,在项目跟目录下创建文件 pytest.ini
在文件中 pytest.ini 中配置 用例标记、

[pytest]
markers=a
		b
		c

通过装饰器@pytest.mark.标记 标记用例
执行测试时添加参数 -m 标记即可

–html=存放测试报告的路径
可以绝对路径,可以相对路径

运行

import pytest
#注意:1.  测试本文件的直接将 __file__ 加上,如果收集测试整个包下的则直接将__file__删除掉  , 
# main中括号里面时列表的形式存在
if __name__=='__main__':
	pytest.main(['-s','-v',__file__])
#在cmd中  直接  
pytest 参数  文件路径
#第二种方式:
python -m pytest 参数  文件路径

跳过

有三种方式:
方式一:强制跳过被装饰的测试方法、测试函数,要借助装饰器 @pytest.mark.skip(reason=“原因”)
方式二:@pytest.mark.skipif(condition,reason)
condition:满足某种条件,bool 表达式
reason:原因
方式三:跳过pytest.skip() 之后所有代码,在测试方法、测试函数种添加代码 pytest.skip()

失败测试用例重跑

要安装模块:pytest-rerunfailures
安装: pip install pytest-rerunfailures

装饰器:@pytest.mark.flaky(reruns=n,reruns-delay=t)
reruns=n, 设置重跑的次数
reruns-delay=t, 设置间隔时间, 单位是s

import pytest
class Test_abc():
		@pytest.mark.flaky(reruns=2,reruns-delay=1)
		def test_a():
			print("this is a test_a")
if __name___=="__main__"
	pytest.main(['-q',__file__])  
	#表示在本文件下,采用极简模式运行
	

命令行运行 (就是放在cmd中运行):—reruns n --reruns-delay t

pytest --reruns 3 --reruns-delay 1 -v ./test_ad_use.py

参数化:
@pytest.mark.parameterize(‘参数。。’,valuse)
注意: 这里参数必须要于函数中或者方法的形参保持一致
values, 测试数据,以列表的形式传入

#一个参数,测试数据保存在一维列表当中
import pytest
class Test_abc():
	@pytest.mark.parameterize('n',[1,2,3,4])
	def test_a(self,n):
		print(n)
if __name__=="__main__":
	pytest.main(['-q',__file__])
	
import pytest
#两个形参的时候,测试数据保存在二维列表当中
class Test_abc():
	@pytest.mark.parameterize('m,n,t',[[1,2,3],[4,5,6]])
	def test_a(m,n,t):
		print(m,n,t)
if __name__=="__main__":
	pytest.main(['-q',__fiel__])

前置和后置

模块级,作用范围为当前模块,所有用例执行前后分别运行1次其前置和后置
setup_module() , 前置,所有用例执行前分别执行1次
teardown_module(),后置, 所有用例执行前分别执行1次
函数级,作用范围为当前模块中的函数,每一条用例执行前后分别运行1次前置,后置
setup_function()
teardown_function()
类级,作用范围为当前类,类中所有用例执行前后分别执行运行1次前置和后置
setup_class()
teardown_class()
方法级,作用范围在当前模块中的方法中,方法中所有用例执行前后分别运行1次前置和后置
setup_method()/setup()
teardown_method()/teardown()

fixture

基本使用
1.在项目的根目录下创建文件 conftest.py
2.在文件中 conftest.py 中创建fixture
@pytest.fixture(name,scope,params,autouse)

  • name,fixture 名称,如果不指定则默认为被装饰的函数或者方法的名称
  • scope ,作用范围(package,session,module,class,function (默认))
  • autouse ,设置为True, 可以实现自动调用fixture
  • 例子:
import pytest
import requests
def login():
	#前置
	request=requests.session()  #保持会话
	url="http://127.0.0.1:5216/login"
	data={'account':'1001','passwd':'123456'}
	rest=request.post(url=url,data=data)
	print(rest.json())
	yield request   #生成器(特点:返回session对象,记住当前的位置,下次在执行下面的代码)
	#后置
	url="http://127.0.0.1:5216/login_out"
	rest=request.get(url=url,data=data)
	print(rest.json())
	
	

```python
#在函数或者方法中直接通过fixture的名称引用就是了
import pytest  # 导入模块
class Test_Query_Book:

    def query_book(self,rq,bk_no=None,bk_name=None,bk_author=None):
        url = 'http://localhost:5600/query_book'
        data = {'bk_no': bk_no, 'bk_name': bk_name, 'bk_author':bk_author}
        res = rq.get(url=url,params=data)
        return res.json()
    @pytest.mark.parametrize('case',[['使用图书编号查询','101234567890',None,None,1000],
                                     ['使用图书作者查询',None,None,'Mr.Deng',1000]])
    def test_case(self,fix,case):  # 编写测试用例
        rq = fix   # 获取fixture的返回值
        actual_result = self.query_book(rq=rq,bk_no=case[1],bk_name=case[2],bk_author=case[3])
        assert actual_result['code'] == case[-1]

if __name__ == '__main__':
    pytest.main(['-sv',__file__])


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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值