自动化测试--验证邮件内容

场景

业务上有许多发送邮件的场景,发送的邮件基本上都是自动发送的,而且邮件内容是很重要的,对于邮件发没发送,发送的时间点对不对每次回归测试工作量太大了,所以考虑把这部分内容加入到自动化测试中

工具

  • python

  • gmail

    要访问gmail先要去console.cloud.google.com创建访问凭证,如图所示,进行下载后获取一个json文件credentials.json
    在这里插入图片描述

实现代码

其中DateFormat 和get_path是自定义方法,分别是获取时间和获取文件

from __future__ import print_function
import base64
import os.path
import logging
import timefrom utils.get_file_path import get_path
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from utils.date_format import DateFormat
from datetime import datetime
# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly', 'https://www.googleapis.com/auth/gmail.modify']class GmailSearch:def __init__(self):"""get token.json."""self.creds = None# The file token.json stores the user's access and refresh tokens, and is# created automatically when the authorization flow completes for the first# time.file_token = get_path('token.json', 'utils')if os.path.exists(file_token):self.creds = Credentials.from_authorized_user_file(file_token, SCOPES)# If there are no (valid) credentials available, let the user log in.if not self.creds or not self.creds.valid:if self.creds and self.creds.expired and self.creds.refresh_token:self.creds.refresh(Request())else:flow = InstalledAppFlow.from_client_secrets_file(get_path('credentials.json', 'utils'), SCOPES)self.creds = flow.run_local_server(port=0)# Save the credentials for the next runwith open(file_token, 'w') as token:token.write(self.creds.to_json())def search_email(self, **kwargs):'''search email by keywords ( from, sender , subject, before, after, unread, interval):param kwargs: 默认查询当前时间前后10分钟未读的邮件, 如果第一次未查询到,默认会间隔10s钟查询一次,共查询三次, 如果找到的话,会将找到的标记成已读查询主题参数: subject发送人参数: sender是否已读 : unread (bool类型)查询时间段参数: before, after设置查询间隔: interval设置查询次数: count:return:  the email, if no result is found, return none'''count = kwargs.get("count") if kwargs.get("count") is not None else 3if count == 0:return "no email found"search_str = ["in:inbox"]unread = False if kwargs.get("unread") else Trueif unread:search_str.append("is:unread")if kwargs.get("attachment"):search_str.append("has:attachment")if kwargs.get("sender"):  # value like atest@email.com, btest@email.comsearch_str.append(f'from:({kwargs.get("sender")})')if kwargs.get("to"):  # value like atest@email.com, btest@email.comsearch_str.append(f'to:({kwargs.get("to")})')if kwargs.get("subject"): search_str.append(f'subject:({kwargs.get("subject")})')if kwargs.get("before"):search_str.append(f'before:{kwargs.get("before")}')else:  # default value is current + 10.minutessearch_str.append(f'before:{DateFormat.from_current_minutes(10)}')if kwargs.get("after"):search_str.append(f'after:{kwargs.get("after")}')else:  # default value is current - 10.minutessearch_str.append(f'after:{DateFormat.from_current_minutes(-10)}')interval = kwargs.get("interval") if kwargs.get("interval") else 10query = " ".join(search_str)unread = kwargs.get("unread")time.sleep(interval)logging.info(datetime.now().strftime("%H:%M:%S"))logging.info(str(count - 1))try:# Call the Gmail APIservice = build('gmail', 'v1', credentials=self.creds)results = service.users().messages().list(userId='me', q=query).execute()messages = results.get("messages")if not messages:logging.info('No email found, continue to search')kwargs.update({"count": count-1})return self.search_email_content(**kwargs)# get the last email, mark read, return email body# body = []last_email = service.users().messages().get(userId='me', id=messages[0]['id']).execute()payload = last_email['payload']# internalDate = last_email['internalDate']# The Body of the message is in Encrypted format. So, we have to decode it.# Get the data and decode it with base 64 decoder.parts = payload.get('parts')[0]['body'] if payload.get('parts') else payload.get('body')data = parts['data']data = data.replace("-", "+").replace("_", "/")decoded_data = base64.b64decode(data)body = str(decoded_data, 'utf-8')# mark readif unread:logging.info(" mark read");service.users().messages().modify(userId='me', id=messages[0]['id'],body={'removeLabelIds': ['UNREAD']}).execute()return bodyexcept HttpError as error:logging.info(f'An error occurred: {error}')# test=GmailSearch()
# test.search_email(before='2023/10/3', after='2023/9/25', to="test@test.com", unread=True)

参考文档:Gmail api文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/132922.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

了解计算机的大小端存储模式

我们在计算机中存储数据时,数据是如何组织和表示的是一个重要的问题。其中一个关键概念是 大小端存储模式(Endianness),它描述了多字节数据在内存中的存储方式。本文将介绍大小端存储模式的原理、应用和区别。 什么是大小端存储模…

通过全流量查看部门或客户端网络使用情况

近年来,随着数字化转型和云计算服务的广泛应用,组织和企业对于网络带宽和性能的需求也在不断增长。 网络的稳定性、性能和安全性对于业务流程的顺畅运行至关重要。因此,了解部门或客户端网络的使用情况是网络管理和优化的关键。本文将通过Ne…

Docker数据管理、网络与Cgroup资源限制

目录 一、Docker的数据管理 1、数据卷 2、数据卷容器 3、端口映射 4、容器互联 二、Docker网络 2.1Docker网络实现原理 2.2Docker 的网络模式 3.3网络模式详解: host模式 container模式 none模式 bridge模式 自定义网络 创建自定义网络 三、Cgroup资源…

Maven修改仓库和镜像地址

目录 1、修改仓库地址2、修改镜像地址 1、修改仓库地址 使用IDEA时,如果不指定自己下载的Maven,idea会默认使用自带的Maven 3(bundle)。maven 3默认的仓库路径一般是在c盘的用户文件夹中的.m2目录下: 当maven下的pom文件中的依赖逐渐增加时,maven仓库下…

0基础学习VR全景平台篇第116篇:认识修图软件Photoshop

上课!全体起立~ 大家好,欢迎观看蛙色官方系列全景摄影课程! 今天给大家讲解修图软件Photoshop,下面我们开始吧! (PS软件课程大纲) 1.Photoshop是什么 发明人Adobe Photoshop,简称…

剑指Offer-推理二叉树

剑指Offer-推理二叉树 LCR 124. 推理二叉树 题目如下 某二叉树的先序遍历结果记录于整数数组 preorder,它的中序遍历结果记录于整数数组 inorder。请根据 preorder 和 inorder 的提示构造出这棵二叉树并返回其根节点。 注意:preorder 和 inorder 中均…

JavaScript作用域实战

● 首先,我们先创建一个函数,和以前一样,计算一个年龄的 function calcAge(birthYear) {const age 2037 - birthYear;return age; }● 然后我们创建一个全局变量,并调用这个函数 const firstName "IT知识一享"; cal…

Thread类的基本操作(JAVA多线程)

线程是操作系统中的概念,操作系统内核实现了线程这样的机制,并提供了一些API供外部使用。 JAVA中 Thread类 将系统提供的API又近一步进行了抽象和封装,所以如果想要使用多线程就离不开 Thread 这个类。 线程的创建(Thread类) 在JAVA中 创建…

中国多主数据库:压强投入,期待破茧

拿破仑曾说:“战争的艺术就是在某一点上集中最大优势兵力”,强调了力量集中的重要性。 如今,国际形势风云变幻,西方世界对中国的围剿不再仅仅体现在军事和地缘政治上,而更多表现在经济与科技上。在科技领域&#xff0…

Akshare获取同花顺行业

使用akshare可以很方便的获取同花顺行业列表,与每个行业对应的个股信息,流程如下: 使用ak.stock_board_industry_summary_ths()获取行业列表循环行业列表,使用ak.stock_board_industry_cons_ths()获取行业对应的个股信息 官方文…

MySQL数据库入门到大牛_02_MySQL环境搭建、演示使用、图形化管理工具、一二章练习

文章目录 1. MySQL的卸载步骤1:停止MySQL服务步骤2:软件的卸载步骤3:残余文件的清理步骤4:清理注册表(选做)步骤5:删除环境变量配置 2. MySQL的下载、安装、配置2.1 MySQL的4大版本2.2 软件的下…

Python基础(第五期): python数据容器(序列) 列表 集合 元素 字符串 字典 序列遍历操作

python基础专栏 python基础(第五期) 文章目录 python基础(第五期)数据容器一、列表1、列表的定义2、列表的下标索引 3、列表的(添加)方法3.1 列表的查询方法3.2 修改特定下标索引的值3.3 列表指定位置插入元素3.3 列表指定元素的追…

【Linux】-文件操作(重定向、缓冲区以及Linux下一切皆文件的详解)

💖作者:小树苗渴望变成参天大树🎈 🎉作者宣言:认真写好每一篇博客💤 🎊作者gitee:gitee✨ 💞作者专栏:C语言,数据结构初阶,Linux,C 动态规划算法🎄 如 果 你 …

电脑监控软件丨2023全网最详细解析

电脑监控软件是一个比较敏感的话题,因为很多员工会觉得电脑监控侵犯了自己的隐私,电脑上企业会觉得安装软件只不过是为了保护自己的核心利益。 对于此,我们要辩证的看待。 今天我们从企业的角度出发,谈谈电脑监控软件的话题。 必…

【python VS vba】(5) 在python中使用xlwt操作Excel(待完善ing)

目录 1 什么是xlwt 2 导入xlwt 3 相关语法 3.1 创建新的workbook 3.2 创建新的sheet 3.3 保存workbook 4 python里表格的形式 4.1 矩阵 4.2 EXCEL的数据形式 完全等于矩阵的数字结构 4.3 python里矩阵 5 具体代码 5.1 代码 5.2 结果 5.3 要注意的问题 5.3.1 不能…

NOIP2023模拟12联测33 D. 滈葕

NOIP2023模拟12联测33 D. 滈葕 文章目录 NOIP2023模拟12联测33 D. 滈葕题目大意思路code 题目大意 思路 放一段题解的材料 ABO 血型系统是血型系统的一种,把血液分为 A,B,AB,O 四种血型。血液由红细胞和血清等组成,红细胞表面 有凝集原,血清…

LangChain+LLM实战---Midjourney(v5.1) Prompt深度剖析

原文:Anatomy of Midjourney Promps: In-Depth Study for effective Prompting Strategies — V5.1 examples 作者:Michael King 你是否曾经发现自己盯着Midjourney的空白画布,手指悬停在键盘上,让我问自己:“我应该…

kafka问题汇总

报错1: 解决方式 1、停止docker服务   输入如下命令停止docker服务 systemctl stop docker 或者service docker stop1   停止成功的话,再输入docker ps 就会提示出下边的话: Cannot connect to the Docker daemon. Is the docker daem…

方案分享:F5机器人防御助企业应对复杂攻击

企业是Bot攻击者的目标,网络犯罪分子会不断调整他们的攻击,来攻破愈发成熟的Bot防护,这使企业安全团队时刻处于紧张状态。如果不能有效地管理Bot,应用性能、客户体验和业务都会被影响,但在尝试阻止这些攻击时&#xff…

k8s service

文章目录 Service 基础概念Service 类型:Service 的工作流程:东西流量,南北流量NodePortLoadBalancer Service 基础概念 在 Kubernetes(K8s)中,Service 是一个抽象的概念,表示一个应用程序的逻…