2023最全最细的Selenium+Pytest自动化测试框架实战

本文详述了使用Selenium+Pytest构建自动化测试框架的全过程,包括管理时间、添加配置文件、记录日志、理解POM模型、元素定位、封装Selenium基类、创建页面对象、编写测试用例、执行测试、生成测试报告以及发送邮件等步骤,旨在提供一个全面的实战教程。
摘要由CSDN通过智能技术生成

选前言#  

selenium自动化+ pytest测试框架

本章你需要

  • 一定的python基础——至少明白类与对象,封装继承

  • 一定的selenium基础——本篇不讲selenium,不会的可以自己去看selenium中文翻译网


测试框架简介#

  • 测试框架有什么优点呢:

    • 代码复用率高,如果不使用框架的话,代码会很冗余
    • 可以组装日志、报告、邮件等一些高级功能
    • 提高元素等数据的可维护性,元素发生变化时,只需要更新一下配置文件
    • 使用更灵活的PageObject设计模式
  • 测试框架的整体目录

    目录/文件 说明 是否为python包
    common 这个包中存放的是常见的通用的类,如读取配置文件
    config 配置文件目录
    logs 日志目录
    page 对selenium的方放进行深度的封装
    page_element 页面元素存放目录
    page_object 页面对象POM设计模式,本人对这个的理解来自于苦叶子的博客
    TestCase 所有的测试用例集
    utils 工具类
    script 脚本文件
    conftest.py pytest胶水文件
    pytest.ini pytest配置文件

  这样一个简单的框架结构就清晰了。

知道了以上这些我们就开始吧!

我们在项目中先按照上面的框架指引,建好每一项目录。

注意:python包为是的,都需要添加一个__init__.py文件以标识此目录为一个python包。


首先管理时间#

首先呢,因为我们很多的模块会用到时间戳,或者日期等等字符串,所以我们先单独把时间封装成一个模块。

然后让其他模块来调用即可。在utils目录新建times.py模块

<span style="color:#596172"><span style="background-color:#ffffff"><code class="language-python"><span style="color:#5c6370"><em>#!/usr/bin/env python3</em></span>
<span style="color:#5c6370"><em># -*- coding:utf-8 -*-</em></span>
<span style="color:#7171bf">import</span> time
<span style="color:#7171bf">import</span> datetime
<span style="color:#7171bf">from</span> functools <span style="color:#7171bf">import</span> wraps


<span style="color:#7171bf">def</span> <span style="color:#61aeee">timestamp</span>():
    <span style="color:#98c379">"""时间戳"""</span>
    <span style="color:#7171bf">return</span> time.time()


<span style="color:#7171bf">def</span> <span style="color:#61aeee">dt_strftime</span>(fmt=<span style="color:#98c379">"%Y%m"</span>):
    <span style="color:#98c379">"""
    datetime格式化时间
    :param fmt "%Y%m%d %H%M%S
    """</span>
    <span style="color:#7171bf">return</span> datetime.datetime.now().strftime(fmt)


<span style="color:#7171bf">def</span> <span style="color:#61aeee">sleep</span>(seconds=<span style="color:#d19a66">1.0</span>):
    <span style="color:#98c379">"""
    睡眠时间
    """</span>
    time.sleep(seconds)


<span style="color:#7171bf">def</span> <span style="color:#61aeee">running_time</span>(func):
    <span style="color:#98c379">"""函数运行时间"""</span>

<span style="color:#61aeee">    @wraps(func)</span>
    <span style="color:#7171bf">def</span> <span style="color:#61aeee">wrapper</span>(*args, **kwargs):
        start = timestamp()
        res = func(*args, **kwargs)
        <span style="color:#7171bf">print</span>(<span style="color:#98c379">"校验元素done!用时%.3f秒!"</span> % (timestamp() - start))
        <span style="color:#7171bf">return</span> res

    <span style="color:#7171bf">return</span> wrapper


<span style="color:#7171bf">if</span> __name__ == <span style="color:#98c379">'__main__'</span>:
    <span style="color:#7171bf">print</span>(dt_strftime(<span style="color:#98c379">"%Y%m%d%H%M%S"</span>))

</code></span></span>

添加配置文件#

配置文件总是项目中必不可少的部分!

将固定不变的信息集中在固定的文件中

conf.py#

项目中都应该有一个文件对整体的目录进行管理,我也在这个python项目中设置了此文件。

在项目config目录创建conf.py文件,所有的目录配置信息写在这个文件里面。

<span style="color:#596172"><span style="background-color:#ffffff"><code class="language-python"><span style="color:#5c6370"><em>#!/usr/bin/env python3</em></span>
<span style="color:#5c6370"><em># -*- coding:utf-8 -*-</em></span>
<span style="color:#7171bf">import</span> os
<span style="color:#7171bf">from</span> selenium.webdriver.common.by <span style="color:#7171bf">import</span> By
<span style="color:#7171bf">from</span> utils.times <span style="color:#7171bf">import</span> dt_strftime


<span style="color:#7171bf">class</span> <span style="color:#61aeee">ConfigManager</span>(<span style="color:#61aeee">object</span>):
    <span style="color:#5c6370"><em># 项目目录</em></span>
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

    <span style="color:#5c6370"><em># 页面元素目录</em></span>
    ELEMENT_PATH = os.path.join(BASE_DIR, <span style="color:#98c379">'page_element'</span>)

    <span style="color:#5c6370"><em># 报告文件</em></span>
    REPORT_FILE = os.path.join(BASE_DIR, <span style="color:#98c379">'report.html'</span>)

    <span style="color:#5c6370"><em># 元素定位的类型</em></span>
    LOCATE_MODE = {
        <span style="color:#98c379">'css'</span>: By.CSS_SELECTOR,
        <span style="color:#98c379">'xpath'</span>: By.XPATH,
        <span style="color:#98c379">'name'</span>: By.NAME,
        <span style="color:#98c379">'id'</span>: By.ID,
        <span style="color:#98c379">'class'</span>: By.CLASS_NAME
    }

    <span style="color:#5c6370"><em># 邮件信息</em></span>
    EMAIL_INFO = {
        <span style="color:#98c379">'username'</span>: <span style="color:#98c379">'1084502012@qq.com'</span>,  <span style="color:#5c6370"><em># 切换成你自己的地址</em></span>
        <span style="color:#98c379">'password'</span>: <span style="color:#98c379">'QQ邮箱授权码'</span>,
        <span style="color:#98c379">'smtp_host'</span>: <span style="color:#98c379">'smtp.qq.com'</span>,
        <span style="color:#98c379">'smtp_port'</span>: <span style="color:#d19a66">465</span>
    }

    <span style="color:#5c6370"><em># 收件人</em></span>
    ADDRESSEE = [
        <span style="color:#98c379">'1084502012@qq.com'</span>,
    ]

<span style="color:#61aeee">    @property</span>
    <span style="color:#7171bf">def</span> <span style="color:#61aeee">log_file</span>(self):
        <span style="color:#98c379">"""日志目录"""</span>
        log_dir = os.path.join(self.BASE_DIR, <span style="color:#98c379">'logs'</span>)
        <span style="color:#7171bf">if</span> <span style="color:#7171bf">not</span> os.path.exists(log_dir):
            os.makedirs(log_dir)
        <span style="color:#7171bf">return</span> os.path.join(log_dir, <span style="color:#98c379">'{}.log'</span>.<span style="color:#7171bf">format</span>(dt_strftime()))

<span style="color:#61aeee">    @property</span>
    <span style="color:#7171bf">def</span> <span style="color:#61aeee">ini_file</span>(self):
        <span style="color:#98c379">"""配置文件"""</span>
        ini_file = os.path.join(self.BASE_DIR, <span style="color:#98c379">'config'</span>, <span style="color:#98c379">'config.ini'</span>)
        <span style="color:#7171bf">if</span> <span style="color:#7171bf">not</span> os.path.exists(ini_file):
            <span style="color:#7171bf">raise</span> FileNotFoundError(<span style="color:#98c379">"配置文件%s不存在!"</span> % ini_file)
        <span style="color:#7171bf">return</span> ini_file


cm = ConfigManager()
<span style="color:#7171bf">if</span> __name__ == <span style="color:#98c379">'__main__'</span>:
    <span style="color:#7171bf">print</span>(cm.BASE_DIR)
</code></span></span>

注意:QQ邮箱授权码点击查看生成教程

这个conf文件我模仿了Django的settings.py文件的设置风格,但是又有些许差异。

在这个文件中我们可以设置自己的各个目录,也可以查看自己当前的目录。

遵循了约定:不变的常量名全部大写,函数名小写。看起来整体美观。

config.ini#

在项目config目录新建一个config.ini文件,里面暂时先放入我们的需要测试的URL

<span style="color:#596172"><span style="background-color:#ffffff"><code class="language-ini"><span style="color:#e06c75">[HOST]</span>
<span style="color:#d19a66">HOST</span> = https://www.baidu.com
</code></span></span>

读取配置文件#

配置文件创建好了,接下来我们需要读取这个配置文件以使用里面的信息。

我们在common目录中新建一个readconfig.py文件

<span style="color:#596172"><span style="background-color:#ffffff"><code class="language-python"><span style="color:#5c6370"><em>#!/usr/bin/env python3</em></span>
<span style="color:#5c6370"><em># -*- coding:utf-8 -*-</em></span>
<span style="color:#7171bf">import</span> configparser
<span style="color:#7171bf">from</span> config.conf <span style="color:#7171bf">import</span> cm

HOST = <span style="color:#98c379">'HOST'</span>


<span style="color:#7171bf">class</span> <span style="color:#61aeee">ReadConfig</span>(<span style="color:#61aeee">object</span>):
    <span style="color:#98c379">"""配置文件"""</span>

    <span style="color:#7171bf">def</span> <span style="color:#61aeee">__init__</span>(self):
        self.config = configparser.RawConfigParser()  <span style="color:#5c6370"><em># 当有%的符号时请使用Raw读取</em></span>
        self.config.read(cm.ini_file, encoding=<span style="color:#98c379">'utf-8'</span>)

    <span style="col
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值