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

news2024/11/27 7:36:43

场景

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

工具

  • 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 time

from 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 run
            with 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 3
        if count == 0:
            return "no email found"
        search_str = ["in:inbox"]
        unread = False if kwargs.get("unread") else True
        if 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.com
            search_str.append(f'from:({kwargs.get("sender")})')
        if kwargs.get("to"):  # value like atest@email.com, btest@email.com
            search_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.minutes
            search_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.minutes
            search_str.append(f'after:{DateFormat.from_current_minutes(-10)}')
        interval = kwargs.get("interval") if kwargs.get("interval") else 10
        query = " ".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 API
            service = 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 read
            if unread:
                logging.info(" mark read");
                service.users().messages().modify(userId='me', id=messages[0]['id'],
                                                  body={'removeLabelIds': ['UNREAD']}).execute()
            return body

        except 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.coloradmin.cn/o/1166948.html

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

相关文章

精选8款UML图工具,闭眼入!

在现代软件开发领域,UML(统一建模语言)图是不可或缺的工具之一,用于可视化和通信复杂系统的结构和设计。然而,在选择合适的UML图工具时,你需要考虑多个因素,如项目规模、团队协作需求、功能复杂…

【Unity实战】最全面的库存系统(四)

文章目录 先来看看最终效果前言问题新增数据库,自动添加物品唯一ID物品配置唯一的ID替换原来的instanceID丢弃物品每次只丢弃一个物品问题完结先来看看最终效果 前言 本期紧跟着上期,继续来完善我们的库存系统,实现存储物品唯一ID和加载功能,丢弃物品功能 问题 instance…

【方法】如何解压ZIP格式压缩文件?

ZIP是一种常见的压缩文件格式,可以将一个或多个文件和文件夹打包成单个文件,以减少存储空间和传输时间。那想要读取压缩包里的文件,要如何解压呢? 压缩和解压压缩包,都需要用到解压缩软件,下面来分享一下3…

一键翻译,批量重命名,让文件夹名更贴心!

在日常生活和工作中,我们经常需要处理大量的文件夹。有时候,我们需要根据特定的需求对这些文件夹进行重命名。但是,手动重命名每个文件夹不仅耗时且容易出错。现在,我们的文件改名工具为你提供了一键翻译、批量重命名的便捷服务&a…

C语言调试技巧(debug)及程序运行时出现的问题

目录 一、什么是调试 1.介绍调试 2.Debug与Release 3.Debug与Release的对比 二、怎么调试 1.介绍几个调试快捷键 2.调试的时候查看程序当前信息 三、常见编程错误 1.编译型错误(最简单) 2.链接型错误 3.运行时错误(最难&#xff0…

stm32F407系列控制板用户手册

stm32F407系列控制板用户手册 文章目录 stm32F407系列控制板用户手册1.外观和接口标注2.功能3.参数4.应用场景 1.外观和接口标注 2.功能 智能配网远程控制多路舵机接口多路电机接口姿态实时采集ps 接口oled屏OTA固件一键升级语音控制-需借助app语音识别功能预留can接口预留多个…

IPMI接口配置

1.IPMI接口和RJ45的网口外观上一样,一般主板上带有的IPMI接口会和网卡分开放置,具体区分还要看主板的Specification,下面红色部分的即为IPMI接口 2.找到IPMI接口后,我们要接上一根网线。然后开机进入BIOS,具体按那个…

请一个折腾了5个月AI绘画的人来讲讲GPU选择的经验,没入坑的看他这一篇就足够了

一个折腾了5个月AI绘画的人来讲讲经验,基本上入坑只需要看这一篇就可以了。 不说废话,首先,将显卡分成专业级和家用级。然后两个级别里面再各分高中低一共6档,我一档一档说,包括大家关心的移动版显卡以及显存升级问题…

备忘录在电脑里叫什么?Win10系统自带的备忘录在哪打开?

对于每天都需要使用电脑来办公的职场人士来说,能够随手在电脑桌面上记录工作笔记、常用工作资料、工作注意事项等内容是非常有必要的。但是如果想要实现在电脑上随手记录事情,就需要先找到一款类似于备忘录或便签软件那样的记事软件。 那么备忘录在电脑…

datagrip出现 java.net.ConnectException: Connection refused: connect.

出现这样的情况要看一下hadoop有没有启动 start-all.sh nohup /export/server/apache-hive-3.1.2-bin/bin/hive --service hiveserver2 & scp -r /export/server/apache-hive-3.1.2-bin/ node3:/export/server/ /export/server/apache-hive-3.1.2-bin/bin/hive show databa…

Linux - 安装Ubuntu虚拟机

1,安装VMware Workstation 16 Player,然后运行。 2,选择安装一个新的虚拟机和之后安装操作系统。 3,选择Linux Ubuntu 64-bit 4,填写虚拟机名字和存放的路径。 5,选择硬盘大小。 6,可以定制硬…

Appium 结合 TestNG 并行执行测试

Appium 测试框架可以让我们使用不同的编程语言(Java、Python、Ruby、JavaScript)测试不同移动端平台的应用(Android、iOS),目前也是最火的移动端测试框架。这篇文章会带着大家学习到如何在不同设备中并行执行测试。 并…

Oracle数据库两表关联更新

先放结论 UPDATE 需要更新的表名 BSET B.更新字段1 更新内容1, B.更新字段2 更新内容2WHERE EXISTS (SELECT 1FROM 关联表名 AWHERE A.关联字段 B.关联字段AND A.筛选字段1 筛选字段1 AND A.筛选字段2 筛选字段2 AND B.筛选字段3 筛选字段3 );问题分析 需要写一个更新语…

凝聚伙伴力量,共赢产业未来—— 麒麟信安云展信创重庆站活动圆满召开

志合越山海,聚力共前行!11月1日下午,麒麟信安云展信创重庆站圆满召开。 本次活动邀请业内专家、权威机构、行业客户、合作伙伴齐聚一堂,围绕产业新机遇、新挑战,产业政策及趋势等内容展开研讨交流,同时分享…

【SFM】《Structure-from-Motion Revisited》

论文 论文代码 资料 cvpr2017 COLMAP 文章目录 2. 本文贡献2.1 Scene Graph Augmentation 场景图增强2.2 Next Best View Selection下一个最佳视图选择2.3 鲁棒高效的三角化 2.4 BA(Bundle Adjustment)2.4.1 参数化求解方法2.4.2 过滤2.4.3 再三角化&…

企业大数据挖掘平台推荐

大数据挖掘平台适合哪些应用场景呢? 1、适合大型企业 分布式云计算,线性扩展,保证性能,与BI平台无缝整合,一键发布挖掘模型,模型库提高知识复用,减少重复投入,支持跨库…

当科技遇上神器:用Streamlit定制AI可视化问答界面

Streamlit是一个开源的Python库,利用Streamlit可以快速构建机器学习应用的用户界面。 本文主要探讨如何使用Streamlit构建大模型外部知识检索的AI问答可视化界面。 我们先构建了外部知识检索接口,然后让大模型根据检索返回的结果作为上下文来回答问题。…

UPS设备还只知道人工巡检?这个神器你一定要试试!

随着电子设备在我们的生活和工作中扮演越来越重要的角色,电力的可靠性变得至关重要。不间断电源系统作为一种关键设备,可以提供电力备份,以保障设备在电力中断或波动的情况下能够正常运行。然而,UPS设备的有效监控和管理对于确保其…

unity 使用TriLib插件动态读取外部模型

最近在做动态加载读取外部模型的功能使用了triLib插件,废话不多说直接干货。 第一步下载导入插件,直接分享主打白嫖共享,不搞花里胡哨的。 链接:https://pan.baidu.com/s/1DK474wSrIZ0R6i0EBh5V8A 提取码:tado 导入后第…

录屏软件免费版,精选3款,助你轻松录制!

录屏软件在今天的数字时代中扮演着重要的角色,无论是为了创建教育教程、分享游戏成就,还是记录计算机上的操作步骤。然而,许多用户面临付费和高级功能的限制,很难找到合适的免费录屏软件。那录屏软件免费版都有哪些呢?…