Python+Selenium+Pytest+PO+Allure+DDT+Log实现Web UI自动化测试

Python+Selenium+Pytest+PO+Allure+DDT实现Web UI自动化测试

前言

Python:编程语言

Pytest](https://so.youkuaiyun.com/so/search?q=pytest&spm=1001.2101.3001.7020):独立的、全功能的Python单元测试框架

Selenium:用于Web应用程序测试的工具,测试框架

Allure:测试报告

DDT:数据驱动

一、前置条件

1. 安装Python开发环境

1.1 Python解释器
3.8.0版本

1.2 Pycharm集成开发环境
专业版

2.下载览器驱动

下载浏览器驱动,浏览器驱动版本要与浏览器版本一致。

下载地址:

Chrome:http://npm.taobao.org/mirrors/chromedriver/
Firefox:https://github.com/mozilla/geckodriver/releases
Edge:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
Safari:https://webkit.org/blog/6900/webdriver-support-in-safari-10/

  • 浏览器驱动加到python环境变量中: path
  • 或者chromedriver.exe与python.exe放在同一个目录
  • 运行时也可以指定Chromedriver的路径
    本项目中将驱动chromedriver.exe放到工程的driver目录下-固定目录。

注:MCX调度台 查看浏览器驱动的版本

1、ctrl + F12  调出element窗口
2、点击Console  输入 'navigator.userAgent'  注意区分大小写

3.安装allure

1)下载allure,下载网址 https://github.com/allure-framework/allure2/releases
2)解压到电脑本地(此目录后续使用,不要动),配置环境变量(把allure目录下的bin目录配置到系统环境变量中的path路径)
参考博客《allure报告框架介绍》https://blog.youkuaiyun.com/weixin_59868574/article/details/135502984。

  1. 下载第三方库

工程新建requirements.txt,输入以下内容,之后安装requirements.txt文件,或单个安装

pytest== 7.4.2
selenium== 3.141.0
urllib3==1.26.18
PySocks~=1.7.1
PyYAML~=6.0.1
psutil~=5.9.7
allure-pytest~=2.13.2

二、测试框架整体目录

在这里插入图片描述

三、测试工具类utils

3.1 管理时间timer.py

包括时间戳,日期等其他模块会使用的字符串,将时间封装成一个单独的模块,让其他模块来调用。

在 utils目录新建timer.py模块

"""
@File    : timer.py
@Author  : TJC
@Date    : 2023/7/10 
@Desc    :时间字符串管理
"""
import time
import datetime
from functools import wraps


def timestamp():
    """时间戳"""
    return time.time()


def dt_strftime(fmt="%Y%m"):
    """
    datetime格式化时间
    :param fmt “%Y%m%d %H%M%S
    """
    return datetime.datetime.now().strftime(fmt)


def sleep(seconds=1.0):
    """睡眠时间"""
    time.sleep(seconds)


def running_time(func):
    """函数运行时间"""

    @wraps(func)
    def wrapper(*args, **kwargs):
        start = timestamp()
        res = func(*args, **kwargs)
        print("校验元素done!用时%.3f秒!" % (timestamp() - start))
        return res

    return wrapper


if __name__ == '__main__':
    print(dt_strftime("%Y%m%d %H%M%S"))

3.2 日志管理logger.py

测试脚本需要记录运行日志,所以将日志管理封装成一个模块,用于被其他模块调用。
在utils目录中新建logger.py模块,代码如下:

"""
@File    : logger.py
@Author  : TJC
@Date    : 2023/7/10
@Desc    :日志管理模块
"""

import logging
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler
from config.config import cm


class Log:
    def __init__(self, seg):

        self.seg = seg

        # 创建logger
        self.logger = logging.getLogger()
        if not self.logger.handlers:
            self.logger.setLevel(logging.DEBUG)

            # 定义日志文件大小为10M
            max_bytes = 10 * 1024 * 1024
            # 定义保留的文件数量为50个
            backup_count = 50

            # 创建日志文件处理器,备份文件命名规则默认为添加后缀数字,数字越大时间越早
            if self.seg == "time":
                fh = TimedRotatingFileHandler(cm.log_file, when='D', backupCount=backup_count, encoding='utf-8')
                """
                :param:when
                        'S':每秒切分日志文件
                        'M':每分钟切分日志文件
                        'H':每小时切分日志文件
                        'D':每天切分日志文件(默认值)
                        'W0' ~ 'W6':每星期切分日志文件(0表示星期一,1表示星期二,以此类推)
                        'midnight':每天午夜切分日志文件 与'D'相同
                :param:interval  默认1,1D就是一天
                """
                fh.setLevel(logging.INFO)
            else:
                fh = RotatingFileHandler(cm.log_file, maxBytes=max_bytes, backupCount=backup_count, encoding='utf-8')
                fh.setLevel(logging.INFO)

            # 创建一个handle输出到控制台
            ch = logging.StreamHandler()
            ch.setLevel(logging.INFO)

            # 定义输出的格式
            formatter = logging.Formatter(self.fmt)
            fh.setFormatter(formatter)
            ch.setFormatter(formatter)keyi

            # 添加到handle
            self.logger.addHandler(fh)
            self.logger.addHandler(ch)

    @property
    def fmt(self):
        return '%(levelname)s\t%(asctime)s\t[%(filename)s:%(lineno)d]\t%(message)s'

# 使用时间分割log文件,可以修改when参数,建议在性能测试脚本中使用
# log = Log('time').logger
# 使用大小分割log文件
log = Log('size').logger

四、配置文件夹config

4.1 公共配置config.py

将所有的文件目录,文件位置,封装后被其他模块调用,如果新增文件或新增目录,在这里添加方法。
在config目录下新建模块config.py,代码如下:

"""
@File    : config.py
@Author  : TJC
@Date    : 2023/7/10
@Desc    :工程的文件目录,文件位置
"""

import os
from utils.timer import dt_strftime


class ConfigManager:
    """
    管理项目目录,文件
    """

    DIR_CURR = os.path.abspath(__file__)

    DIR_CONF = os.path.dirname(os.path.abspath(__file__))

    # 项目路径
    DIR_BASE = os.path.dirname(DIR_CONF)

    DIR_COMM = os.path.join(DIR_BASE, "common")

    DIR_UTIL = os.path.join(DIR_BASE, "utils")

    # 页面元素和页面对象路径
    DIR_PAGE = os.path.join(DIR_BASE, 'page_object')

    # 页面元素
    DIR_ELEMENT = os.path.join(DIR_BASE, "page_element")

    DIR_DRIVER = os.path.join(DIR_BASE, "driver")

    @property
    def web_ini_file(self):
        """ web 配置文件"""
        ini_file = os.path.join(self.DIR_CONF, 'web_cfg.ini')
        if not os.path.exists(ini_file):
            raise FileNotFoundError("配置文件%s不存在!" % ini_file)
        return ini_file

    @property
    def dir_report_json(self):
        """allure报告目录 json文件"""
        report_dir = os.path.join(self.DIR_BASE, 'report')
        os.makedirs(report_dir, exist_ok=True)
        json_dir = os.path.join(report_dir, 'json')
        os.makedirs(json_dir, exist_ok=True)
        return json_dir

    @property
    def dir_report_html(self):
        """allure报告目录 html文件"""
        report_dir = os.path.join(self.DIR_BASE, 'report')
        os.makedirs(report_dir, exist_ok=True)
        html_dir = os.path.join(report_dir, 'html')
        os.makedirs(html_dir, exist_ok=True)
        return html_dir

    @property
    def dir_log(self):
        """日志目录"""
        log_dir = os.path.join(self.DIR_BASE, 'logs')
        os.makedirs(log_dir, exist_ok=True)
        return log_dir

    @property
    def log_file(self):
        """日志文件"""
        return os.path.join(self.dir_log, '{}.log'.format(dt_strftime()))

    @property
    def dir_img(self):
        """截图目录"""
        img_dir = os.path.join(self.dir_log, 'images')
        os.makedirs(img_dir, exist_ok=True)
        re
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值