使用pytest+selenium+allure实现web页面自动化测试

news2024/9/21 10:33:26

测试文件

  • base 基本方法
  • data 测试数据
  • page web页面相关操作
  • image 测试截图
  • log 日志文件
  • report 测试报告文件
  • temp 临时文件
  • tool 文件读取,发邮件文件
  • TestCases 测试用例

在page下的__init__.py文件下配置

import os
import time
from selenium.webdriver.common.by import By

# 项目路径
PROJECT_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 图片路径
IMAGE_PATH = os.path.join(PROJECT_PATH, 'image')
# 测试数据路径
DATA_PATH = os.path.join(PROJECT_PATH, 'data')
# 日志路径
LOG_PATH = os.path.join(PROJECT_PATH, 'log')
# 测试报告
REPORT_PATH = os.path.join(PROJECT_PATH, 'report', 'html')
# 临时文件
TEMP_PATH = os.path.join(PROJECT_PATH, 'temp')
# 请求url
url = "http://cal.apple886.com/"

"""  邮件信息  """
email_host = "smtp.qq.com"  # SMTP服务器
email_sender = '2022204437@qq.com'  # 发件人
email_license = 'jxyvidactsaiicja'  # 授权码
email_receivers = ['2022204437@qq.com']  # 收件人(可以群发)

""" 以下为测试数据配置文件 """
image_path = os.path.join(IMAGE_PATH, '%serror.png' % time.strftime("%Y%m%d%H%M%S"))

"""  以下为测试数据配置文件   """
add_data = os.path.join(DATA_PATH, 'add.json')
multi_data = os.path.join(DATA_PATH, 'multi.json')
subtr_data = os.path.join(DATA_PATH, 'subtr.json')

"""  以下为logger配置文件   """
log_filename = os.path.join(LOG_PATH, '%sdemo.log' % time.strftime("%Y%m%d%H%M%S"))
log_when = "midnight"
log_interval = 1
log_backupCount = 30
log_encoding = "utf-8"
log_filemode = "w"
log_format = "%(asctime)s -[%(name)s]- %(levelname)s---[%(filename)s [%(funcName)s:%(lineno)s]] - %(message)s"
log_datefmt = "%Y-%m-%d %H:%M:%S"

""""   以下为计算机配置数据   """
computer_add = By.XPATH, '//*[@id="simpleAdd"]'
computer_subtr = By.XPATH, '//*[@id="simpleSubtr"]'
computer_multi = By.XPATH, '//*[@id="simpleMulti"]'
computer_divi = By.XPATH, '//*[@id="simpleDivi"]'
computer_clear = By.XPATH, '//*[@id="simpleClearAllBtn"]'
computer_equal = By.XPATH, '//*[@id="simpleEqual"]'
computer_value = By.XPATH, '//*[@id="resultIpt"]'

在base下创建一个webpage.py文件

from selenium.webdriver.support.wait import WebDriverWait
from web.counter.base.logger import GetLogger
from web.counter import page

log = GetLogger().get_logger()


class WebPage:

    def __init__(self, driver):
        log.info("初始化driver{}".format(driver))
        self.driver = driver

    # 查找元素
    def base_find_element(self, loc, timeout=30, poll_frequency=0.5):
        log.info("正在查找元素{}".format(loc))
        return WebDriverWait(
            self.driver, timeout=timeout, poll_frequency=poll_frequency).until(
            lambda x: x.find_element(*loc))

    # 点击
    def base_click(self, loc):
        log.info("点击元素{}".format(loc))
        self.base_find_element(loc).click()

    # 输入
    def base_input(self, loc, key):
        log.info("输入元素{}输入值为{}".format(loc,key))
        self.base_find_element(loc).clear()
        self.base_find_element(loc).send_keys(key)

    # 获取文本
    def base_get_test(self, loc):
        log.info("获取文本{}".format(loc))
        return self.base_find_element(loc).text

    # 获取属性值
    def base_get_value(self, loc):
        log.info("获取{}属性值".format(loc))
        return self.base_find_element(loc).get_attribute('value')

    # 截图
    def base_get_image(self):
        log.error("错误!!!错误!!!错误!!!")
        self.driver.get_screenshot_as_file(page.image_path)

在base下创建一个driver.py文件

from selenium import webdriver
from web.counter import page


class GetDriver:
    driver = None

    @classmethod
    def get_driver(cls):
        if cls.driver is None:
            cls.driver = webdriver.Edge()
            cls.driver.maximize_window()
            cls.driver.get(page.url)
        return cls.driver

    @classmethod
    def quit_driver(cls):
        if cls.driver:
            cls.driver.quit()
            cls.driver = None

在base下创建一个logger.py文件

import logging.handlers
from web.counter import page


class GetLogger:
    logger = None

    @classmethod
    def get_logger(cls):
        if cls.logger is None:
            # 获取日志器
            cls.logger = logging.getLogger()
            # 获取日志器级别
            cls.logger.setLevel(logging.INFO)
            # 获取处理器 控制台
            sh = logging.StreamHandler()
            # 获取处理器 文件-以以时间分隔
            th = logging.handlers.TimedRotatingFileHandler(
                filename=page.log_filename,
                when=page.log_when,
                interval=page.log_interval,
                backupCount=page.log_backupCount,
                encoding=page.log_encoding)
            fm = logging.Formatter(page.log_format)
            sh.setFormatter(fm)
            th.setFormatter(fm)
            cls.logger.addHandler(th)
            cls.logger.addHandler(sh)
        return cls.logger

在page下创建一个add_page.py文件

from selenium.webdriver.common.by import By

from web.counter.base.webpage import WebPage
from web.counter import page


class AddPage(WebPage):
    # 点击数字
    def page_click_num(self, num):
        for n in str(num):
            loc = By.XPATH, '//*[@id="simple{}"]'.format(n)
            self.base_click(loc)

    # 点击加号
    def page_click_add(self):
        self.base_click(page.computer_add)

    # 点击等于
    def page_click_equal(self):
        self.base_click(page.computer_equal)

    # 获取结果
    def page_get_value(self):
        return self.base_get_value(page.computer_value)

    # 清屏
    def page_click_clear(self):
        self.base_click(page.computer_clear)

    # 截图
    def page_get_image(self):
        self.base_get_image()

    # 组装加法
    def page_add(self, a, b):
        self.page_click_num(a)
        self.page_click_add()
        self.page_click_num(b)
        self.page_click_equal()


在TestCases 下创建一个test_add.py文件

from time import sleep
import pytest
from web.counter.page.add_page import AddPage
from web.counter.base.driver import GetDriver
from web.counter.tool.read_json import GetJson
from web.counter.base.logger import GetLogger
from web.counter import page

log = GetLogger().logger


class TestAdd:

    def setup_class(self):
        self.computer = AddPage(GetDriver().get_driver())

    def teardown_class(self):
        GetDriver().quit_driver()

    @pytest.mark.parametrize("a, b, result", GetJson().get_data(page.add_data))
    def test_add_computer(self, a, b, result):
        self.computer.page_click_clear()
        self.computer.page_add(a, b)
        try:
            assert self.computer.page_get_value() == str(result)
        except:
            log.error("错误")
            sleep(1)
            self.computer.page_get_image()
            raise

在tool下创建一个read_json.py文件

import json


class GetJson:
    data_lists = None
    data_dic = None

    # 读取json文件
    @classmethod
    def read_json(cls, json_path):
        with open(json_path, "r", encoding="utf-8") as f:
            return json.load(f)

    # 获取测试数据
    @classmethod
    def get_data(cls, json_path):
        cls.data_dic = cls.read_json(json_path)
        cls.data_lists = list()
        for data in cls.data_dic.values():
            cls.data_lists.append((data.get("a"), data.get("b"), data.get("result")))
        return cls.data_lists

在tool下创建一个send_emails.py文件

import time
import zipfile
import os
from email.mime.application import MIMEApplication
from web.counter import page
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart


class SendEmails:
    def __init__(self):
        self.mime = MIMEMultipart()
        self.allure_report = None
        self.report_path = page.REPORT_PATH
        self.temp_path = page.TEMP_PATH

    def send_email(self):
        self.mime['Subject'] = '%sxxx测试报告' % time.strftime('%Y年%m月%d日 %H:%M:%S ')
        content = 'hello, this is email content.'
        textApart = MIMEText(content)
        zip_Apart = MIMEApplication(open(SendEmails().make_zip, 'rb').read())
        zip_Apart.add_header('Content-Disposition', 'attachment', filename='allure_report.zip')

        self.mime.attach(textApart)
        self.mime.attach(zip_Apart)
        try:
            server = smtplib.SMTP(page.email_host)
            server.login(page.email_sender, page.email_license)
            server.sendmail(page.email_sender, page.email_receivers, self.mime.as_string())
            print('发送成功')
            server.quit()
        except smtplib.SMTPException as e:
            print('error:', e)  # 打印错误

    # 打包目录为zip文件(实际未压缩)
    @property
    def make_zip(self):
        if not os.path.exists(self.temp_path):
            os.makedirs(self.temp_path)
        self.allure_report = os.path.join(self.temp_path, 'allure_report.zip')
        zip_file = zipfile.ZipFile(self.allure_report, 'w')
        for present, dirs, files in os.walk(self.report_path):
            """
                present:现在的目录
                dirs:该目录下包含的子目录
                files:该目录下包含的文件
            """
            for file in files:
                pathfile = os.path.join(present, file)
                relpath = os.path.relpath(pathfile, page.PROJECT_PATH)  # 相对路径
                # ZIP_STORED:实际上并未压缩。
                zip_file.write(pathfile, relpath, zipfile.ZIP_STORED)
        zip_file.close()
        return self.allure_report


if __name__ == '__main__':
    report = page.REPORT_PATH
    temp = page.TEMP_PATH
    print(report)
    print(temp)
    SendEmails().send_email()
    print(SendEmails().allure_report)
    print("压缩包创建完成")

# import zmail
# from web.counter import page
#
#
# def send_report():
#     """发送报告"""
#
#     with open(page.REPORT_PATH, encoding='utf-8') as f:
#         content_html = f.read()
#     try:
#         mail = {
#             'from': '2022204437@qq.com',
#             'subject': '最新的测试报告邮件',
#             'content_html': content_html,
#             'attachments': [page.REPORT_PATH, ]
#         }
#         server = zmail.server(*page.EMAIL_INFO.values())
#         server.send_mail(page.ADDRESSEE, mail)
#         print("测试邮件发送成功!")
#     except Exception as e:
#         print("Error: 无法发送邮件,{}!", format(e))
#
#
# if __name__ == "__main__":
#     '''请先在config/conf.py文件设置QQ邮箱的账号和密码'''
#     send_report()

web自动化大体就是这样,然后测试数据可以自己写

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

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

相关文章

【小沐学Unity3d】3ds Max 减面工具:Simplyon(Unity3d,Python)

文章目录 1、简介2、下载安装2.1 安装Simlygon插件2.2 安装USD插件 3、使用测试4、Python测试结语 1、简介 Simplygon 带有一个 Unity 插件,它公开了优化功能,例如缩减、聚合、重新划分网格、冒名顶替者(SingleView、BillboardCloud / Veget…

PDF控件Spire.PDF for .NET【安全】演示:将加密或解密 PDF 文件

当涉及到在 Internet 上共享机密文档时,PDF 加密是一项至关重要的任务。通过使用强密码加密 PDF 文件,您可以保护文件数据免遭未经授权的人员访问。在某些情况下,可能还需要删除密码才能公开文档。在本文中,您将了解如何使用Spire…

spring-validation实现分组校验

文章目录 前言实际开发可能会使用到分组校验maven添加依赖简单使用高级应用分组自定义分组组合分组 源码地址 前言 JSR 303中提出了Bean Validation,表示JavaBean的校验,Hibernate Validation是其具体实现,并对其进行了一些扩展,…

WEB绘图插件Canvas基础应用

一、概述 canvas 是 html5 标准中提供的⼀个标签 顾名思义是定义在浏览器上的画布,通过其强大的绘图接口,我们可以实现各种各样的图形, 炫酷的动画 ,甚至可以利用他开发⼩游戏,包括市面上很流行的数据可视化框架底层都…

【新手必看】PyCharm2023免费下载安装配置教程+Python环境搭建、图文并茂全副武装学起来才嗖嗖的快,绝对最详细!

🚀 个人主页 极客小俊 ✍🏻 作者简介:web开发者、设计师、技术分享博主 🐋 希望大家多多支持一下, 我们一起学习和进步!😄 🏅 如果文章对你有帮助的话,欢迎评论 💬点赞&a…

logback.xml

logback.xml <?xml version"1.0" encoding"UTF-8"?> <configuration><!-- 日志存放路径 --><property name"log.path" value"./logs" /><!-- 日志输出格式 --><property name"log.pattern&q…

释放潜力:前端开发者转向鸿蒙的必备建议

如果需要JavaScript知识点可以去我的主要观看 大家有关于JavaScript知识点不知道可以去 &#x1f389;博客主页&#xff1a;阿猫的故乡 &#x1f389;系列专栏&#xff1a;JavaScript专题栏 &#x1f389;ajax专栏&#xff1a;ajax知识点 &#x1f389;欢迎关注&#xff1a;&am…

【离散数学】——期末刷题题库(图论应用题)

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

力扣:203. 移除链表元素(Python3)

题目&#xff1a; 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 …

Windows 截图工具①FastStone Capture ②PixPin

​ 今天说说Windows好用的载图软件&#xff1a; 2023年12月21日&#xff0c;更新新增 PixPin 2款超级好用的截图软件&#xff0c;不止是载图、编辑、录屏、Gif等好用的功能&#xff0c;本人一直也在用。 ①FastStone Capture ②PixPin 软件介绍&#xff1a;FastStone Fast…

2024年【公路水运工程施工企业安全生产管理人员】考试题及公路水运工程施工企业安全生产管理人员报名考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【公路水运工程施工企业安全生产管理人员】考试题及公路水运工程施工企业安全生产管理人员报名考试&#xff0c;包含公路水运工程施工企业安全生产管理人员考试题答案和解析及公路水运工程施工企业安全生产管理…

还在用nvm?来试试更快的node版本管理工具——fnm

前言 &#x1f4eb; 大家好&#xff0c;我是南木元元&#xff0c;热衷分享有趣实用的文章&#xff0c;希望大家多多支持&#xff0c;一起进步&#xff01; &#x1f345; 个人主页&#xff1a;南木元元 目录 什么是node版本管理 常见的node版本管理工具 fnm是什么 安装fnm …

4+miRNA+机器学习生信思路,常规又简单的miRNA也能发4+

今天给同学们分享一篇生信文章“Machine learning algorithms reveal potential miRNAs biomarkers in gastric cancer”&#xff0c;这篇文章发表在Sci Rep期刊上&#xff0c;影响因子为4.6。 结果解读&#xff1a; 数据来源 本研究包括348名男性&#xff08;占64.9%&#x…

解析资产管理的革新之路:从手工盘点到易点易动RFID散步式方案

随着科技的不断进步和应用&#xff0c;资产管理领域也在不断演进和革新。从最初的手工盘点到现代的智能化解决方案&#xff0c;我们目睹了资产管理的巨大变革。其中&#xff0c;易点易动RFID散步式方案以其高效、准确和便捷的特点&#xff0c;正在成为资产管理的新宠。本文将深…

Linux之yum管理器

目录 yum管理器 yum相关指令 yum list yum list | grep yum install yum remove 拓展 1.yum install -y man-pages 2.切换yum源 3.yum install -y epel-release 4. yum install -y lrzsz rz指令 sz指令 在window系统上&#xff0c;我们会在电脑自带的应用商…

Android Studio使用Genymotion

1. Genymotion介绍 GenyMotion速度之快令人发指&#xff0c;模拟效果堪比真机调试&#xff0c;支持绝大部分的模拟器功能&#xff0c;甚至包括语音&#xff0c;Google Now&#xff0c;支持eclipse, android studio。非常适合用来开发和演示效果。 2. Genymotion下载 Genymotio…

上 GitHub 热榜,星星暴涨,这个项目相继超越了 Archery, Flyway 和 Yearning

「 登上 GitHub Trending 星星超越 Yearning 键盘的敲击不停 传播开发的福音 」⚡️ Bytebase 是一款面向开发和 DBA 的一站式数据库 CI/CD 工具。它的所有代码都开源在 GitHub 上。GitHub 也是我们触达全球用户的核心阵地。虽然 GitHub Star 数一直是一个饱受争议的指标&a…

深度学习模型压缩方法:剪枝方法分类介绍

本文将介绍深度学习模型压缩方法中的剪枝,内容从剪枝简介、剪枝步骤、结构化剪枝与非结构化剪枝、静态剪枝与动态剪枝、硬剪枝与软剪枝等五个部分展开。 一、剪枝简介 在介绍剪枝之前,首先介绍过参数化这个概念,过参数化主要是指在训练阶段,在数学上需要进行大量的微分求解…

外贸函电开发信模板?写客户开发邮件方法?

如何写好外贸函电开发信&#xff1f;英语函电中的开发信怎么写&#xff1f; 在国际贸易中&#xff0c;外贸函电开发信扮演着至关重要的角色。这是一种有效的沟通工具&#xff0c;用来建立和维护与潜在客户或合作伙伴的联系。在这篇文章中&#xff0c;蜂邮将为您提供一个外贸函…

数字化营销的未来:TikTok在圣诞季的流量引爆与转化

随着数字化时代的发展&#xff0c;社交媒体平台成为品牌数字营销不可或缺的一部分。而TikTok&#xff0c;以其独特的短视频形式和强大的用户基础&#xff0c;正逐渐崭露头角。本文将探讨TikTok在圣诞季的数字化营销策略&#xff0c;着重分析流量的引爆和转化&#xff0c;以及数…