摘要:一前言上一章曲鸟全栈自动化教学七使用来搭建自动化测试框架的教学中,我们搭建了一个自动化测试框架的雏形,做到了数据和代码的分离。这篇会为对框架代码进行讲解。
上一章《曲鸟全栈UI自动化教学(七):使用Pytest来搭建自动化测试框架》 的教学中,我们搭建了一个自动化测试框架的雏形,做到了数据和代码的分离。这篇会为对框架代码进行讲解。
项目目录文件就下面五个,核心的主要在test_case.py
和comDef.py
这两个文件中
程序运行的入口文件为main.py
,当我们运行main.py
文件时,会执行pytest.main
方法进行测试用例的注册:
import pytest# 执行测试用例pytest.main(["test_case.py"])
上面的代码等于将test_case.py
这个文件中的pytest的测试用例进行执行,test_case.py
文件代码如下 (注释是对该行代码的解释说明):
import pytestimport timefrom selenium.webdriver.common.by import Byfrom selenium import webdriverfrom comDef import parse_case# 初始化driverdriver = 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 pytestimport timefrom selenium.webdriver.common.by import Byfrom selenium import webdriverfrom comDef import parse_case# 初始化driverdriver = 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) if value else getattr(driver, action)() else: return False
我们之前测试用例在excel中编写的,指定操作步骤和定位方法都是输入进去,其实我们可以做一个下来菜单来选择:
下拉选择定位方式:
下拉选择操作方式:
甚至我们还可以改成中文 (相应的解析代码需要做修改(根据/
分割,取最前)):
这样写起来就方便一些了,能够提升一些我们的编写效率。
其实我们常说的自动化测试平台,最直观的也就是将编写编写用例这部分操作放在了平台上进行 (下图是我们自建的自动化测试平台编辑用例的截图):
将各个操作元素、类型以及填写的值都都通过图形化操作的方法进行编辑,而用例、页面元素都通过平台进行管理:
执行操作和结果验证、生成测试报告、定时执行、元素维护等,甚至是失败重跑、重试这些机制都交由后台服务处理。
让编写自动化用例的过程更纯粹,只需要通过“点点点”的方式就能够实现,以至于让完全不懂代码的用户也能够编写自动化测试用例。但构建自动化测试平台的成本是极高的! 所以是选择构建自动化测试平台、还是excel驱动或者其他方式的自动化测试需要根据公司对自动化这一块投入的占比来选择。
另外,无论是我们说的关键字驱动、数据代码分离,还是本教程所建立的框架,都是为了让自动化测试变得简单高效,但在个人接触中发现,有些同行业的小伙伴,花了不少精力去使用各种各样的框架,感觉很高端、很厉害、但当编写用例的时候维护成本反而越来越高。甚至为了能够上手编写自动化用例,还需要花一周、两周去熟悉框架、代码。本来是化繁为简的过程反而弄的越来越复杂,这是得不偿失的!
自动化测试本就是一个回报与投入比较低的事情,而为了这个事情维护了一套框架,不能够提高自动化用例的编写效率,这也是非常讽刺的一件事情。
这里我想表达的主要意思就是:学习自动化可能不同的企业、不同的小伙伴选择的技术架构、框架都不一样,实际不需要去纠结该如何作选择。无论是pytest、allure、robotframework、selenium、airtest都是辅助你进行自动化的工具。最重要的是自己一定要去思考、自己建立的自动化是不是简单高效,易于维护和上手,以及你的企业需要怎样的自动化、什么样的自动化才适合你们的企业才是关键的。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/123514.html
摘要:一前言本专栏将结合元素定位和前沿的图像识别定位两种方法,从到的构建一个企业级自动化测试框架。 一、前言 本专栏将结合元素定位(selenium/appium)和前沿...
摘要:那是怎样知道我们想要操作哪个元素的呢这篇文章将为你讲解的页面操作原理和高效的元素定位方法。它的含义为匹配名称包含的元素。 一、前言 上篇文章中我们成功编写并启动了第...
摘要:一前言上篇文章我们学习了页面操作原理及如何高效的进行元素定位那的工作原理又是什么是如何驱动浏览器的呢这篇文章为你讲解工作原理及对浏览器的配置和操作。基于该运行浏览器所产生的缓存等数据都会被记录。 ...
摘要:玩转同时全面掌握潮流技术采用新一代的开发框架更小更富有表现力更健壮。融合多种常见的需求场景网络请求解析模板引擎静态资源日志记录错误请求处理。结合语句中转中间件控制权,解决回调地狱问题。注意分支中的目录为当节课程后的完整代码。 ?? 与众不同的学习方式,为你打开新的编程视角 独特的『同步学习』方式 文案讲解+视频演示,文字可激发深层的思考、视频可还原实战操作过程。 云集一线大厂...
摘要:并总结经典面试题集各种算法和插件前端视频源码资源于一身的文档,优化项目,在浏览器端的层面上提升速度,帮助初中级前端工程师快速搭建项目。 本文是关注微信小程序的开发和面试问题,由基础到困难循序渐进,适合面试和开发小程序。并总结vue React html css js 经典面试题 集各种算法和插件、前端视频源码资源于一身的文档,优化项目,在浏览器端的层面上提升速度,帮助初中级前端工程师快...
阅读 1435·2021-11-22 12:09
阅读 1716·2021-11-16 11:45
阅读 3478·2021-09-09 09:33
阅读 1289·2019-08-30 13:22
阅读 1942·2019-08-29 17:00
阅读 2498·2019-08-29 16:28
阅读 2803·2019-08-26 13:51
阅读 1058·2019-08-26 13:25