这是我写的 web ui 自动化脚本
UI 自动化脚本已经部署到了 jenkins
这个是接口自动化的脚本,接口自动化目前还没有往 jenkins 部署
我就是想知道,我这跟公司真实的自动化还缺了那些东西,或者说我写的哪里不对?
以后的计划是把框架进行封装,写自动化测试平台
资料有点少,不好评价反馈,只能留点疑问,楼主可以看下有没有做好:
1、UI 自动化里面,框架是否有提供什么机制便于提高用例稳定性?(如找元素的自动等待等)
2、UI 自动化脚本的写法里,怎么尽可能让代码容易复用?(如 PageObject,从代码看有 Page 的概念,但不确定是不是用了 PO 模式)
3、一旦有报错,框架层是否可以捕获并输出足够清晰的日志等信息,便于使用者基于日志就可以定位并解决问题?
接口自动化:
1、一般接口自动化的特点是数量多,如果每一个都得写不少代码的话,编写维护成本会相对高。针对这块是否有评估过一个接口用例按现在框架写,大概要多久?
2、从这个截图看,有不少代码是为把报告输出到 allure 服务的。不确定这部分是不是用例,如果是,可以考虑下把这部分由框架直接代劳,而不用每个用例自己写?
3、类似 UI 自动化,接口自动化也有流程型的用例的,通过调用多个接口形成一个流程进行测试。不知道是否有考虑过脚本如何分层,让流程型用例和单接口用例,都能尽量复用一些公共代码,降低编写成本?
4、接口测试很多时候会需要测试多个环境,从脚本看像是从一个全局配置文件里直接获取 url 的,建议框架可以提供多环境分开配置的能力(类似 spring 里面可以分别为 dev 和 prod 设定不同的配置项对应值)。
资料有点少,不好评价反馈,只能留点疑问,楼主可以看下有没有做好:
1、UI 自动化里面,框架是否有提供什么机制便于提高用例稳定性?(如找元素的自动等待等)
2、UI 自动化脚本的写法里,怎么尽可能让代码容易复用?(如 PageObject,从代码看有 Page 的概念,但不确定是不是用了 PO 模式)
3、一旦有报错,框架层是否可以捕获并输出足够清晰的日志等信息,便于使用者基于日志就可以定位并解决问题?
接口自动化:
1、一般接口自动化的特点是数量多,如果每一个都得写不少代码的话,编写维护成本会相对高。针对这块是否有评估过一个接口用例按现在框架写,大概要多久?
2、从这个截图看,有不少代码是为把报告输出到 allure 服务的。不确定这部分是不是用例,如果是,可以考虑下把这部分由框架直接代劳,而不用每个用例自己写?
3、类似 UI 自动化,接口自动化也有流程型的用例的,通过调用多个接口形成一个流程进行测试。不知道是否有考虑过脚本如何分层,让流程型用例和单接口用例,都能尽量复用一些公共代码,降低编写成本?
4、接口测试很多时候会需要测试多个环境,从脚本看像是从一个全局配置文件里直接获取 url 的,建议框架可以提供多环境分开配置的能力(类似 spring 里面可以分别为 dev 和 prod 设定不同的配置项对应值)。
最近在研究这方面的东西,就是想知道,我写的这个跟真实的公司做自动化差别在哪里?
脚本距离框架还有很长的路要走,要想做一个团队都能用的框架,至少要解决几个问题:1
1、用例去脚本化,比如 Excel、json 维护用例
2、入参数据解决,比如数据库依赖、接口依赖
3、断言问题与问题 2 类似
4、登录、加解密、验证码等项目非通用性问题
5、报告输出,不能光有简单的执行结果,还要统计接口数、覆盖率等更丰富的数据展示维度
共勉
https://gitee.com/zx660644/uitest
落地了的 ui 自动化项目
看了,你的回复,我先修改下 ui 自动化的测试框架,UI 的问题,你说的 1,2,3, 2 和 3 有做,但是还是有问题,1 我用的隐式等待和强制等待,觉得不太好,打算改
https://blog.csdn.net/dream_back/article/details/118751500
我找了一篇博客,看了别人封装的 po,觉得我现在的 po 有很大问题,定位元素的部分太过繁琐,而且还把业务的测试流程放在 page 里了
页面就是页面 动作就是动作 页面只维护元素对象 动作单独抽象出来 不建议写在页面对象里
写用例时再把元素和动作组合起来
可以参考下 RF 的设计 ,动作就是动作 元素就是元素
执行用例时 就是元素 + 动作 来完成一次操作 比如
1、用户名元素 + 输入 (参数)
2、密码元素 + 输入(参数)
3、登录按钮元素 + 左键点击
打个比方
类似于 selenium 本身也封装了 click 方法
你可以再封装一层 把 driver.click + Action 类的 Click + JavaScript 的 Click 封装到一起 做成自定义的动作 myClick 简化脚本开发的操作
嗯,我设计的确实这块问题很大,已经在重构了,打算封装一个基类 basepage 把启动浏览器,元素定位的类型,操作等单独封装起来
楼主,代码可以贴代码。markdown 的代码块。别截图。
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as ec
class Page():
def __init__(self):
self.driver = webdriver.Chrome()
def open(self):
self.driver.get("https://www.baidu.com")
self.driver.maximize_window()
def __find_element__(self, lc, locator):
"""元素定位"""
if lc == "id":
ele = self.driver.find_element(By.ID, locator)
print(type(ele))
WebDriverWait(self.driver, 10).until(ec.visibility_of_element_located(ele))
a=Page()
a.open()
a.__find_element__('id','kw').send_keys('python')
我打算重构的 basepage 页,简单调试了下,报了这个错
<class 'selenium.webdriver.remote.webelement.WebElement'>
Traceback (most recent call last):
File "D:/demo_123/basic/page.py", line 48, in <module>
a.__find_element__('id','kw').send_keys('python')
File "D:/demo_123/basic/page.py", line 19, in __find_element__
WebDriverWait(self.driver, 10).until(ec.visibility_of_element_located((ele)))
File "D:\demo_123\venv\lib\site-packages\selenium\webdriver\support\wait.py", line 81, in until
value = method(self._driver)
File "D:\demo_123\venv\lib\site-packages\selenium\webdriver\support\expected_conditions.py", line 125, in _predicate
return _element_if_visible(driver.find_element(*locator))
TypeError: find_element() argument after * must be an iterable, not WebElement
元素的定位方式和用例数据可以单独抽离出来,实现脚本与数据分离
def find_element(self, lc, locator,timeout=''):
"""元素定位"""
if lc == "xpath":
ele = WebDriverWait(self.driver, timeout=10)\
.until(EC.visibility_of_element_located((By.XPATH,locator)))
class Login_Page_Locator(BasePage):
"""登录页元素定位"""
username = ('xpath', '//input[@placeholder="请输入用户名"]')
password = ('xpath', '//input[@placeholder="请输入密码"]')
submit = ('xpath','//span[text()="登录"]')
class Test_Login(object):
loginpage = Login_Page_Locator()
base = BasePage()
@allure.story("登录用例")
@allure.severity(allure.severity_level.BLOCKER)
def test_login1_normal(self):
"""username and passwd is normal"""
Logger().info('test_login success')
try:
#输入用户名
self.base.find_element(self.loginpage.username[0],self.loginpage.username[1]).send_keys(username)
except NoSuchElementException:
Logger().error('login no find element')
#assert username == "admin"
#insert_img("login_normal.png")
为什么我这样写,一直在定位元素
好了,已经解决了上面的问题了,但是不知道为什么会启动两次浏览器,我再看看
还有,帮我看下,我这样写有啥问题吗,我现在感觉这样写,测试用例里面,取定位元素的方式,和值,那块有点繁琐,不知道能不能再优化
base.find_element(loginpage.username[0],loginpage.username[1]).send_keys(username)
就这一块
确实比较繁琐 其实现在的前端响应式框架 基本都得靠 xpath 来定位元素了 所以你可以给个默认值为 xpath 可以省一个参数 另外定位元素的方法还需要多扩展几个 至少要覆盖常用的显示等待预定义条件以及自定义条件的场景
其实如果你是想要做框架的话 最好能让脚本能脱离代码环境 能通过编辑配置文件来编写用例脚本
1、默认为 xpath 如果不是再传可选参数
2、是这个意思 在代码里定义规则和 Api 通过配置文件来实现业务脚本
推荐你看看教程
https://coding.imooc.com/class/592.html
一整套 ui 自动化测试流程落地
嗯,元素定位的方法我写了很多,什么 id,name,等,粘贴的代码只粘贴了一个 xpath 的,确实,我写的时候好多定位都是 xpath, 你说的让脚本脱离代码环境,是说的数据驱动,关键字驱动吗,这个我有考虑做,后面计划是想做成这样
去看 poium 和 seldom 项目,github 自己找,那是落地的工程类项目,不是 kpi 项目