一、前言
上一章《曲鸟全栈UI自动化教学(六):开始实战吧!实战环境准备》 我们通过使用禅道真正的实现了第一个实战脚本,文末的练习题小伙伴实现了吗?下面为你公布答案。
二、公布上一章练习题答案
记得把你对应谷歌浏览器版本的chromedriver
放入项目中:
import datetime import random import time from selenium import webdriver from selenium.webdriver.common.by import By driver = webdriver.Chrome() driver.implicitly_wait(2) driver.maximize_window() driver.get('http://127.0.0.1/zentao/user-login.html') time.sleep(0.5) driver.find_element(By.XPATH,'//*[@id="account"]').send_keys('admin') time.sleep(0.5) driver.find_element(By.XPATH,'//*[@id="loginPanel"]/div/div[2]/form/table/tbody/tr[2]/td/input').send_keys('替换为你自己的密码') #这里替换为你自己的密码 time.sleep(0.5) driver.find_element(By.XPATH,'//*[@id="submit"]').click() time.sleep(0.5) driver.find_element(By.XPATH,'//*[@id="menuMainNav"]/li[3]/a').click() driver.switch_to.frame('appIframe-product') time.sleep(0.5) y=driver.find_elements(By.XPATH,'//a[@class="btn btn-primary create-product-btn"]') time.sleep(0.5) driver.find_element(By.XPATH,'//*[@id="mainMenu"]/div[2]/a[3]').click() time.sleep(0.5) driver.find_element(By.XPATH,'//*[@id="name"]').send_keys('selenium2') time.sleep(0.5) driver.find_element(By.XPATH,'//*[@id="code"]').send_keys('002') time.sleep(0.5) driver.find_element(By.XPATH,'//*[@id="submit"]').click()
三、答案和不足分析
之前练习题主要是将整个流程进行了串联,其中有个特殊的操作是需要切换iframe,其他就没什么特殊的地方了。
但如果按照上面的代码写的话,实际上是非常冗余和低效的。首先,为了实现每个步骤都等待0.5秒执行,我们在所有步骤代码之间都加了代码time.sleep(0.5),而且对测试用例没有很好的管理,未对操作事件、元素地址等进行封装,导致可读性低、维护性低等。
所以写出自动化脚本很简单,但这并不代表你掌握了自动化,能够胜任一份自动化测试的工作。也正因如此,我们需要搭建自动化测试框架,将数据和代码操作进行分离,封装有用的公共方法来提高我们的效率。
下面我们结合pytest对我们的代码进行一些优化,让自动化框架初具模型。
四、Pytest简单介绍和注意事项
pytest是一个非常成熟的全功能的Python测试框架,功能很全,很灵活,能够与很多第三方插件进行结合,比如:pytest-html(完美html测试报告生成)、pytest-rerunfailures(失败case重复执行)、pytest-xdist(多CPU分发)等;还可以跟类似Jenkins的CI工具进行结合。
小伙伴可能在网上发现很多教程的自动化是下面这样写的,一条用例就要写一个函数方法:
这里极其不推荐这样做的!等于每次写用例还要写代码,这是严重的低效率和低维护的行为,不可取!
五、搭建自动化测试框架
1. 安装pytest
cmd执行如下命令:
pip install pytest -i https://pypi.tuna.tsinghua.edu.cn/simple some-package
2. 框架思路分析
我们理想的效果是测试用例跟代码进行分离,也就是说当我们编写测试用例的时候,不需要去改动哪怕一行代码。
1)数据层面
我们先来分析数据层面,对于Selenium的操作,无论是点击、还是输入、还是强制等待等最多需要四样参数:
元素地址;
定位方式;
操作方式(点击/输入内容/强制等待/访问网址 等);
操作的值(部分操作有,例如:输入内容、强制等待操作需要、点击操作不需要);
清晰明了的知道了每步操作需要干嘛及使用了什么样的参数。
2)代码层面
用例写好了,该考虑如何写代码了。我们需要写个方法来适配上述用例的执行,需要的功能点:
能根据填写的操作方式选择正确的selenium的执行方法,例如上述用例中操作方式为get,那该方法会执行driver.get方法并将【操作的值】中的数据作为网址进行执行;
能够根据用例【定位方式】的内容选择正确的定位方式进行执行;
元素地址能够正确的填写;
操作的值也是同理;
根据上述要求写了如下的代码,先看目录结构:
再看具体代码
1)main.py
:
import pytest # 执行测试用例 pytest.main(['test_case.py'])
2)comDef.py
:
from openpyxl import load_workbook def load_excel(file): """ 用于读取测试用例所在的表格 """ _data = load_workbook(file) _value = _data.active return _value def parse_case(file): """ 用于将excel中的测试用例转为pytest可识别的测试用例 """ excel_value = load_excel(file) _cases = [] for i in range(2, excel_value.max_row + 1): _cases.append({'path': excel_value['B' + str(i)].value, 'location_method': excel_value['C' + str(i)].value, 'action': excel_value['D' + str(i)].value, 'value': excel_value['E' + str(i)].value}) return _cases
3)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() driver.implicitly_wait(2) driver.maximize_window() @pytest.mark.parametrize("data", parse_case('自动化测试用例.xlsx')) def test_run_case(data): path, location_method = data.get('path'), data.get('location_method') action, value = data.get('action'), data.get('value') if path: if location_method: _driver = driver.find_element(getattr(By, location_method), path) if action == '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
3)执行效果
六、总结
上面的代码看不懂不要紧,后面会进行讲解。(完整代码获取可以关注文末下方的公众号回复:项目代码,进行获取)现在我们已经实现了一个自动化测试框架雏形,达到了数据和代码的分离,用户只需要填写excel就能够达到执行自动化测试的效果。
但刚刚也说了,这个框架只是个雏形,很多功能还还需增加,比如:
更多操作的封装(切换iframe,切换窗口,滚动、获取文本等);
每步执行成功失败的校验和结果存储;
元素地址的管理;
测试报告的生成;
基于步骤的断点调试;
用例失败重试;
小伙伴可以先按自己的理解进行上述功能的实现,后续我也会继续进行分享!