曲鸟全栈UI自动化教学(八):框架代码讲解和进一步优化

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 曲鸟全栈UI自动化教学(八):框架代码讲解和进一步优化

一、前言


上一章《曲鸟全栈UI自动化教学(七):使用Pytest来搭建自动化测试框架》 的教学中,我们搭建了一个自动化测试框架的雏形,做到了数据和代码的分离。这篇会为对框架代码进行讲解。

点我或滑至文末获取《21天学通Python》教程<<


二、代码框架讲解


1. 项目目录

项目目录文件就下面五个,核心的主要在test_case.pycomDef.py这两个文件中


image.png


程序运行的入口文件为main.py,当我们运行main.py文件时,会执行pytest.main方法进行测试用例的注册:

import pytest
# 执行测试用例
pytest.main(['test_case.py'])


2. 核心代码讲解

上面的代码等于将test_case.py这个文件中的pytest的测试用例进行执行,test_case.py文件代码如下 (注释是对该行代码的解释说明)

import pytest
import time
from selenium.webdriver.common.by import By
from selenium import webdriver
from comDef import parse_case
# 初始化driver
driver = webdriver.Chrome()  # 初始化webdriver,启动谷歌浏览器
driver.implicitly_wait(2)  # 设置元素的全局等待时间为2秒,当操作元素时,元素2秒内未出现就抛出异常
driver.maximize_window()  # 最大化浏览器窗口
# 调用parse_case方法,对文件名为:“自动化测试用例.xlsx”里的数据进行解析,解析为[{},{}]列表的形式,这样pytest才能够识别
@pytest.mark.parametrize("data", parse_case('自动化测试用例.xlsx'))
# data为excel中的每行记录(步骤)转换成的pytest能识别的代码:{'action': 'send_keys', 'location_method': 'XPATH', 'path': '//*[@id="account"]', 'value': 'admin'}
def test_run_case(data):
    path, location_method = data.get('path'), data.get('location_method')  # 获取元素地址、定位方法
    action, value = data.get('action'), data.get('value')  # 获取要执行的操作、和操作的值(例如;send_keys的value)
    if path:
        if location_method:
            _driver = driver.find_element(getattr(By, location_method), path) # 寻找元素对象
            # 下面为封装的具体操作,根据excel表获取的不同则执行不同的操作
            if action == 'click':  # 如果要执行的操作等于click则执行点击事件
                _driver.click()
            elif action == 'send_keys' and value:
                _driver.send_keys(value)
    elif value:  # 没有元素路径则代表执行的操作不需要元素路径,所以下面封装的操作都是不需要元素路径的
        if action == 'sleep':  # 强制等待
            time.sleep(float(value))
        elif action == 'get':
            driver.get(value)
    else:
        return False

上面的代码本身也有缺陷,首先我们封装的操作比较少,只有click、send_keys、get等这几个简单的操作,但如果我们封装的操作多了,按现在这样的代码写法,代码量会成倍的增加 (下面是增加了四个操作后,操作功能部分代码)

        if action == 'click':  # 如果要执行的操作等于click则执行点击事件
                getattr(_driver, action)()
                _driver.click()
            elif action=='clear':
                _driver.clear()
                _driver.is_displayed()
            elif action == 'send_keys' and value:
                _driver.send_keys(value)
        if action == 'sleep':  # 强制等待
            time.sleep(float(value))
        elif action == 'get':
            driver.get(value)
        elif action == 'refresh':
            driver.refresh()
        elif action == 'quit':
            driver.quit()
        elif action == 'close':
            driver.close()

可以看到代码量越来越多,当我们框架越来越完善的时候,增加的操作更多的时候,就会越来越难以维护,所以我们需要换一种更精简的写法来简化代码。


三、代码优化

我们还是可以通过反射来处理这些操作代码:

未使用反射时的执行操作的代码(而且随着操作增多代码量也会增加):

        if action == 'click':  # 如果要执行的操作等于click则执行点击事件
                getattr(_driver, action)()
                _driver.click()
            elif action=='clear':
                _driver.clear()
                _driver.is_displayed()
            elif action == 'send_keys' and value:
                _driver.send_keys(value)


        if action == 'sleep':  # 强制等待
            time.sleep(float(value))
        elif action == 'get':
            driver.get(value)
        elif action == 'refresh':
            driver.refresh()
        elif action == 'quit':
            driver.quit()
        elif action == 'close':
            driver.close()

使用反射时的执行操作的代码:


getattr(_driver, action)(value) if value else getattr(_driver, action)()
        if action == 'sleep':  # 强制等待
            time.sleep(float(value))
        else:
            getattr(driver, action)(value) if value else getattr(driver, action)()

可以看到,代码减少了很多!而且再增加操作也不会增加我们的代码量!

完整test_case.py代码如下:


import pytest
import time
from selenium.webdriver.common.by import By
from selenium import webdriver
from comDef import parse_case
# 初始化driver
driver = webdriver.Chrome()  # 初始化webdriver,启动谷歌浏览器
driver.implicitly_wait(2)  # 设置元素的全局等待时间为2秒,当操作元素时,元素2秒内未出现就抛出异常
driver.maximize_window()  # 最大化浏览器窗口
# 调用parse_case方法,对文件名为:“自动化测试用例.xlsx”里的数据进行解析,解析为[{},{}]列表的形式,这样pytest才能够识别
@pytest.mark.parametrize("data", parse_case('自动化测试用例.xlsx'))
# data为excel中的每行记录(步骤)转换成的pytest能识别的代码:{'action': 'send_keys', 'location_method': 'XPATH', 'path': '//*[@id="account"]', 'value': 'admin'}
def test_run_case(data):
    path, location_method = data.get('path'), data.get('location_method')  # 获取元素地址、定位方法
    action, value = data.get('action'), data.get('value')  # 获取要执行的操作、和操作的值(例如;send_keys的value)
    if path:
        if location_method:
            _driver = driver.find_element(getattr(By, location_method), path) # 寻找元素对象
            # 通过反射封装操作,根据excel表获取的不同则执行不同的操作
            getattr(_driver, action)(value) if value else getattr(_driver, action)()
    elif value:  # 没有元素路径则代表执行的操作不需要元素路径,所以下面封装的操作都是不需要元素路径的
        if action == 'sleep':  # 强制等待
            time.sleep(float(value))
        else:
            # 通过反射封装操作,根据excel表获取的不同则执行不同的操作
            getattr(driver, action)(value)
    else:
        getattr(driver, action)()


四、测试用例填写优化


我们之前测试用例在excel中编写的,指定操作步骤和定位方法都是输入进去,其实我们可以做一个下来菜单来选择:

下拉选择定位方式:

d146929d8d5e42169d653dc49794880e.png

下拉选择操作方式:

c81bd1c8fa5e40678f6a3cf26f7e8158.png


甚至我们还可以改成中文 (相应的解析代码需要做修改(根据/分割,取最前)):

1ec49fa9098341b694c3166394766a2a.png

这样写起来就方便一些了,能够提升一些我们的编写效率。


五、总结


其实我们常说的自动化测试平台,最直观的也就是将编写编写用例这部分操作放在了平台上进行 (下图是我们自建的自动化测试平台编辑用例的截图):

a9056b33497e4d0f9abc4a3bbeda7cf3.png

将各个操作元素、类型以及填写的值都都通过图形化操作的方法进行编辑,而用例、页面元素都通过平台进行管理:


139dc8a5032740de8cf7c5c56a903486.png


执行操作和结果验证、生成测试报告、定时执行、元素维护等,甚至是失败重跑、重试这些机制都交由后台服务处理。


让编写自动化用例的过程更纯粹,只需要通过“点点点”的方式就能够实现,以至于让完全不懂代码的用户也能够编写自动化测试用例。但构建自动化测试平台的成本是极高的! 所以是选择构建自动化测试平台、还是excel驱动或者其他方式的自动化测试需要根据公司对自动化这一块投入的占比来选择。


另外,无论是我们说的关键字驱动、数据代码分离,还是本教程所建立的框架,都是为了让自动化测试变得简单高效,但在个人接触中发现,有些同行业的小伙伴,花了不少精力去使用各种各样的框架,感觉很高端、很厉害、但当编写用例的时候维护成本反而越来越高。甚至为了能够上手编写自动化用例,还需要花一周、两周去熟悉框架、代码。本来是化繁为简的过程反而弄的越来越复杂,这是得不偿失的!


自动化测试本就是一个回报与投入比较低的事情,而为了这个事情维护了一套框架,不能够提高自动化用例的编写效率,这也是非常讽刺的一件事情。


这里我想表达的主要意思就是:学习自动化可能不同的企业、不同的小伙伴选择的技术架构、框架都不一样,实际不需要去纠结该如何作选择。无论是pytest、allure、robotframework、selenium、airtest都是辅助你进行自动化的工具。最重要的是自己一定要去思考、自己建立的自动化是不是简单高效,易于维护和上手,以及你的企业需要怎样的自动化、什么样的自动化才适合你们的企业才是关键的

目录
相关文章
|
25天前
|
Rust JavaScript 前端开发
ES6 awaitRust UI 框架
ES6 awaitRust UI 框架
|
25天前
|
前端开发 JavaScript
electron ui框架
Electron是一个使用JavaScript, HTML和CSS等前端技术构建跨平台桌面应用程序的框架。
64 0
|
22天前
|
Java 测试技术 持续交付
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
本文重点讲解如何搭建App自动化测试框架的思路,而非完整源码。主要内容包括实现目的、框架设计、环境依赖和框架的主要组成部分。适用于初学者,旨在帮助其快速掌握App自动化测试的基本技能。文中详细介绍了从需求分析到技术栈选择,再到具体模块的封装与实现,包括登录、截图、日志、测试报告和邮件服务等。同时提供了运行效果的展示,便于理解和实践。
64 4
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
|
18天前
|
监控 安全 测试技术
在实施自动化和持续集成的过程中,如何确保代码的安全性和合规性?
在实施自动化和持续集成的过程中,如何确保代码的安全性和合规性?
|
2月前
|
开发框架 人工智能 小程序
小程序常见的 UI 框架
【10月更文挑战第17天】小程序 UI 框架为开发者提供了便捷的工具和资源,帮助他们快速构建高质量的小程序界面。在选择框架时,需要综合考虑各种因素,以找到最适合项目的解决方案。随着技术的不断进步,UI 框架也将不断发展和创新,为小程序开发带来更多的便利和可能性。
55 2
|
25天前
|
Rust 自然语言处理 API
|
2月前
|
机器学习/深度学习 人工智能 运维
构建高效运维体系:从自动化到智能化的演进
本文探讨了如何通过自动化和智能化手段,提升IT运维效率与质量。首先介绍了自动化在简化操作、减少错误中的作用;然后阐述了智能化技术如AI在预测故障、优化资源中的应用;最后讨论了如何构建一个既自动化又智能的运维体系,以实现高效、稳定和安全的IT环境。
68 4
|
2月前
|
运维 Linux Apache
,自动化运维成为现代IT基础设施的关键部分。Puppet是一款强大的自动化运维工具
【10月更文挑战第7天】随着云计算和容器化技术的发展,自动化运维成为现代IT基础设施的关键部分。Puppet是一款强大的自动化运维工具,通过定义资源状态和关系,确保系统始终处于期望配置状态。本文介绍Puppet的基本概念、安装配置及使用示例,帮助读者快速掌握Puppet,实现高效自动化运维。
59 4
|
17天前
|
机器学习/深度学习 数据采集 人工智能
智能运维:从自动化到AIOps的演进与实践####
本文探讨了智能运维(AIOps)的兴起背景、核心组件及其在现代IT运维中的应用。通过对比传统运维模式,阐述了AIOps如何利用机器学习、大数据分析等技术,实现故障预测、根因分析、自动化修复等功能,从而提升系统稳定性和运维效率。文章还深入分析了实施AIOps面临的挑战与解决方案,并展望了其未来发展趋势。 ####
|
26天前
|
机器学习/深度学习 数据采集 运维
智能化运维:机器学习在故障预测和自动化响应中的应用
智能化运维:机器学习在故障预测和自动化响应中的应用
51 4