首页 > 其他分享 >pytest学习

pytest学习

时间:2023-08-01 18:13:26浏览次数:53  
标签:py 学习 print pytest test 执行 def

pytest

参考

https://blog.csdn.net/stetstet/article/details/119221464

https://blog.csdn.net/lovedingd/article/details/98952868

示例

最简单的示例

类级别的示例

运行方式

main方式运行

import pytest
if __name__ == "__main__":
##		pytest.main(['-s','test_example01.py'])
		pytest.main(['-s','test_example01.py'])

文件右键运行

1

​命令行运行​

命令 说明 tag
pytest test_se.py -s 显示print内容 ==辅助==
pytest test_se.py --reruns NUM
重试运行cases。NUM=重试的次数 ==执行==
pytest -x 第x次失败,就停止测试 ==执行== ==失败==
pytest --maxfail=n 出现n个失败就终止测试 ==执行== ==失败==
pytest testing/ 指定测试目录 ==执行==
pytest -k "MyClass” 通过关键字表达式过滤执行 ==执行== ==失败==
pytest test_mod.py::test_func 通过 node id 指定测试用例(nodeid由模块文件名、分隔符、类名、方法名、参数构成) ==执行== ==失败==

常用命令参数

  • 执行当前文件夹下面的所有文件

pytest 文件名/

  • 执行具体的某一测试文件

pytest 脚本名称.py

  • -k 匹配用例名称

执行测试用例名称包含qq的所有用例

pytest -k qq test_1.py

  • -k 根据用例名称排除某些用例

pytest -s -k "not qq" test_1.py

  • -k 同时匹配不同的用例名称

pytest -s -k "wechat or webo" test_1.py

  • 运行.py模块里面的某个函数

pytest test_mod.py::test_func

  • 运行.py模块里面,测试类里面的某个方法

pytest test_mod.py::TestClass::test_method

  • -x 遇到错误时停止测试

pytest -x test_class.py

  • 当用例错误个数达到指定数量时,停止测试

pytest --maxfail=1

  • -q 简单打印,只打印测试用例的执行结果

pytest -q test_1.py

  • -s 详细打印,-v 更加详细的打印,通过的.用pass表示

pytest -s test_1.py

pytest -v test_1.py

使用要求

钩子函数(前置、后置)

不同的作用范围

  • 模块级别

在当前模块下所有用例执行前去调用登录接口

def setup_module():
	buyer_login()
	print('在当前模块下所有用例执行前去调用登录接口')
def teardown_module():
	print('在当前模块下所有用例执行后要做的后置动作')
  • 函数级别

每一条测试用例执行前后都要去执行的动作

def setup_function():
	print('每条测试用例执行前都会执行')
def teardown_function():
	print('每条测试用例执行后都会执行')
  • 类级别

默认的编写规则是类以Test开头

class TestCart:
	def setup_class(self):
		print('当前类下所有的测试用例执行前调用登录接口')
	def teardown_class(self):
		print('当前类下所有的测试用例执行后执行的动作')

参数化(数据驱动)

普通方式

import pytest
test_data = [
    [1, 4, 5],
    [2, 4, 6],
    [1, -1, 0],
    [1, 4, 9]
]

def add(a, b):
return a + b

@pytest.mark.parametrize('val_a,val_b,exp_result', test_data)
def test_add(val_a, val_b, exp_result):
assert add(val_a, val_b) == exp_result

1

笛卡尔积

import pytest

test_data1 = ['aaa', 'cc']

test_data2 = ['zzzzzzz', 'xxxx', 'd']

@pytest.mark.parametrize('val_a', test_data1)
@pytest.mark.parametrize('val_b', test_data2)
def test_add(val_a, val_b):
print (val_a,val_b)

1

conftest.py

名称固定。pytest运行时自动扫描该文件,获取配置的钩子函数

使用场景

  • 如果某个前置和后置在脚本里大量使用,则可以在conftest.py中统一定义一个fixture,来进行使用
  • 但是如果某个前置或者后置,仅仅只在当前测试用例使用,那么就可以使用之前的setup_xxx和teardown_xxx

解决入参存在中文,导致的运行标题乱码

1

创建文件 conftest.py​,复制以下代码,重新运行测试用例

# 解决中文乱码
from typing import List

def pytest_collection_modifyitems(
session: "Session", config: "Config", items: List["Item"]
) -> None:
# item表示每个测试用例,解决用例名称中文显示问题
for item in items:
item.name = item.name.encode("utf-8").decode("unicode-escape")
item._nodeid = item._nodeid.encode("utf-8").decode("unicode-escape")

1

管理fixture

  • scope表示该fixture的作用域
    session表示在本次pytest执行时,只会被执行一次 module表示在每个模块执行时,只会被执行一次 class表示在每个测试类执行时,只会被执行一次 function表示在每个测试用例执行时,都会被执行 package和session基本上差不多
  • autouse表示该fixture函数是否被自动调用,默认是False

设置为True那么会根据作用域自动完成调用 设置为False则需要手动完成调用 手动调用分为两种: [email protected]('get_buyer_token') # 括号里就是fixture函数的名称 2.在测试用例函数参数中直接写上fixture函数的名称

自动调用

conftest.py中加入

@pytest.fixture(scope='session', autouse=True)
def session_start():
    print("session级别的:开始测试啦")

@pytest.fixture(scope='function', autouse=True)
def func_start():
print("function级别的:准备执行测试")

1

手动调用

  • 方法一:使用装饰器,可加载测试类上,也可加载测试方法上

conftest.py中加入

@pytest.fixture(scope='function', autouse=False)
def func_start():
    print("function级别的:准备执行测试")

测试文件中加入

import pytest

def test_1():
print('test1')

@pytest.mark.usefixtures('func_start')
def test_2():
print('test2')

def test_3():
print('test3')

1

  • 方法二:直接写入方法入参中

conftest.py中加入

@pytest.fixture(scope='function', autouse=False)
def func_start():
    print("function级别的:准备执行测试")

测试文件中加入

def test_3(func_start):
    print('test3')

1

存放数据

conftest.py中加入

@pytest.fixture(scope='function', autouse=False)
def func_start():
    return '测试数据'

测试文件中加入

def test_3(func_start):
    print('str: '+func_start)

1

yield 后置处理

conftest.py中加入

@pytest.fixture(scope='function')
def some_data():
    # 前置动作
    print('get data')
    # 返回数据
    yield 'data_id'
    # 后置动作
    print('clear data')

测试文件中加入

def test_4(some_data):
    print(f'the id of the good is : {some_data}')

1

pytest配置文件

固定名称pytest.ini,便于指定范围的用例文件执行

[pytest]
addopts = -sv
testpaths = ./
python_files = test_*.py
python_classes = Test*
python_function = test_*

创建一个py文件,加入以下代码,自动扫描路径下pytest.ini,根据pytest.ini的配置执行测试

if __name__ == '__main__':
    pytest.main()

多断言pytest-assume

即使第一条断言失败,也会判断之后的断言

需装插件pytest-assume

def test_1():
    string1 ='iaosdf'
    pytest.assume(len(string1)>8,f'实际是{False},预期是{False}' )
    string1 = 'iis'
    pytest.assume(len(string1)>8,f'第二次:实际是{False},预期是{False}' )
    string1 = '333333ffdfdfddfd'
    pytest.assume(len(string1)>8,f'第二次:实际是{True},预期是{True}' )

1

Allure测试报告

需装插件allure-pytest

使用

  • 在pytest.ini文件中追加参数
[pytest]
addopts = -sv --alluredir ./report/data --clean-alluredir
testpaths = ./
python_files = test_*.py
python_classes = Test*
python_function = test_*
  • 使用命令行
pytest -sv --alluredir ./report/data --clean-alluredir [pytest测试文件名.py]

会生成./report/date目录,有一堆json文件

1

  • allure命令行工具配置

pycharm中terminal进入到report同级目录执行命令

allure generate ./report/data -o ./report/html --clean

也可以集成至run.py(文件名非固定)文件中

import os
import pytest
if __name__ == '__main__':
    pytest.main()
    os.system('allure generate ./report/data -o ./report/html --clean')

需要在pycharm中打开index.html选择浏览器打开

错误信息

pytest的退出码有六种:

0:所有的测试case都运行成功

1:部分(或者全部)测试case运行结果失败

2:测试执行过程被用户中断(即跑测试case过程中,用户进行Ctrl + C命令)

3:发生了内部错误(可能是python脚本某些运行时错误)

4:pytest命令行使用错误(可能没有传递正确的命令行参数)

5:实际没有执行case(可能是执行了一个空的测试类)

遇到的问题

  1. 运行找不到测试方法

标签:py,学习,print,pytest,test,执行,def
From: https://www.cnblogs.com/Nora-F/p/pytest.html

相关文章

  • beautifulsoup学习记录
    BeautifulSoup库总结1、BeautifulSoup库作用2、BeautifulSoup()方法3、find()、find_all()、selector()、get()方法1、BeautifulSoup库作用用于将爬取到的网页源码(用requests库完成)解析为soup文档,这样做的好处是可以再用BeautifulSoup库中的过滤函数(方法)过滤提取......
  • RASP知识学习笔记
    RASPRASP(Runtimeapplicationself-protection)是一种内置或链接到应用程序环境中的安全技术,与应用程序融为一体,实时监测、阻断攻击,使程序自身拥有自我保护的能力。工作原理RASP技术是一种基于服务器的技术,一旦应用程序运行开始时就会激活。而且,所有RASP产品都包含一个运行时监......
  • 关于菜鸡学习RHEL8的一些小笔记--->LVM逻辑卷
    LVM基础概念:LVM()逻辑卷管理器,主要适用于对Linux环境下面磁盘分区的管理机制在真实的场景中,服务器使用的越久,所产生的数据量就会越来越大,导致硬盘本身空间越来越小;这里针对分区来看,如果想要扩大容量,就得重新挂载硬盘,然后去做数据迁移,这样就会直接导致业务停止运行;#这里分区的大小是在......
  • 学习Java的第11天
    运算符算数运算符:+,-,*,/,%,++,--赋值运算符:=关系运算符:>,<,>=,<=,==,!=instanceof逻辑运算符:&&,||,!位运算符:&,|,^,~,>>,<<,>>>(了解!!!)条件运算符?:扩展赋值运算符:+=,-=,*=,/=packageoperator;publicclassDemo03{publicstaticv......
  • 深度学习-->卷积神经网络
    二维卷积层: frommxnetimportautograd,ndfrommxnet.gluonimportnn#定义函数corr2d,用于实现二维卷积操作defcorr2d(x,k):#获取卷积核的高度和宽度h,w=k.shape#初始化输出y,其形状为(x.shape[0]-h+1,x.shape[1]-w+1)y=nd.ze......
  • 【学习笔记】记忆化搜索
    记忆化搜索目录前置知识:概念:实现:oiwiki:记忆化搜索建议搭配食用。前置知识:深度优先搜索DFS概念:搜索通常通过递归来实现,但是递归过程中往往有很多结果被重复计算,因此降低了搜索的效率。因此记忆化搜索就是再递归的过程中记录已经遍历过的状态与结果,用到的时候再直接取出......
  • Flutter学习之视图体系
    一、前言Flutter是一种全新的响应式跨平台的移动开发框架,越来越多的开发者参与学习或者研究中,确实在iOS和Android平台上能够用一套代码构建出性能比较高的应用程序。我刚开始接触FlutterFlutter中文网看到这么一句话:Widget是Flutter应用程序用户界面的基本构建块。每个Widget都是用......
  • MLOps学习记录
    MLOps是一种机器学习工程文化,基于MLOps的机器学习系统需要具备持续集成(CI)、持续交付(CD)、持续训练(CT)等能力。MLOps和DevOps区别?持续集成(CI)在传统单元测试、集成测试上,还需要基于验证数据进行模型质量评估。持续交付(CD)交付的不是一个软件或服务,而是一个模型,并将其......
  • Android学习系列(39)--Android主题和样式之系统篇(上)
    Android学习系列(39)--Android主题和样式之系统篇(上)【基于最新的Android4.4的源码分析】每家公司或者每个移动团队无不想开发出一套自己的UI框架,融入自己的设计和特性,这必然会去修改android的ui。所以,学习和理解android的UI设计是最基础和非常有必要的。androidui设计最重要的就是......
  • 最小割树 学习笔记
    问题描述给定一张图,求任意两点的最小割。要求跑\(n\)次最大流。做法暴力需要跑\(n^2\)次最大流,然而这样很浪费,因为求出\(u,v\)两点的最小割以后,我们还获得了至少一种最小割方案,可以通过这一方案获得更多信息。注意到假设通过最小割断开后,\(s,t\)所在集合分别为\(S,T......