Selenium Python + flask+ selenium 自动化测试用例管理、执行平台

Jerry li · 2018年08月12日 · 最后由 Jerry li 回复于 2019年02月21日 · 8630 次阅读

前言

之前使用 Python + flask 开发的 selenium 自动化测试用例管理、执行平台,终于克服懒癌把业务相关的信息剥离掉,代码放到了GitHub 上面:

github地址: https://github.com/jerrylizilong/autotest_platform \ https://jerrylizilong.github.io/autotest_platform/ (越整理越发现自己代码写得烂,如有不足请轻拍)

效果介绍原帖地址: https://testerhome.com/topics/11183

执行效果:
执行单条用例:

执行用例集:

autotest_platform(懒得想名字,先这么叫着)

基于python+selenium的自动化测试管理、执行平台。

版本要求:

python 3.4 以上
selenium : 建议使用 3.0 以上版本
mysql : 建议 5.5 以上

1. 管理平台:

基于flask进行开发,进行用例、用例集、步骤等的增删改查等功能。
启动 flask:

python run.py

2. 启动core服务:

python core.py
  • 基于selenium进行封装,从数据库中读取需要执行的测试用例,并转化、执行、记录测试结果及截图。
  • 需结合selenium grid 或 selenium docker 作为节点进行具体执行载体。

3. 启动atx core服务:

python atx_core.py
  • 基于atx 进行封装,从数据库中读取需要执行的测试用例,并转化、执行、记录测试结果及截图。
  • 需安装atxserver(https://github.com/openatx/atx-server),并修改 app/config.py 文件的以下内容:
# atx 配置
isUseATX=True # True 代表使用 atx
ATXHost = 'http://172.16.100.168:8002' # 对应的 atxserver 地址

安装步骤:

1. clone 或下载代码包到本地解压:

git clone https://github.com/jerrylizilong/autotest_platform.git

2. 按requirements.txt 安装依赖:

cd autotest_platform
pip3 install -r requirements.txt

3. 数据库配置:

3.1 创建数据库,并执行 init.sql 建表并初始化配置数据。

3.2修改 app/config.py 中关于数据库部分的配置: host、port、database、user、password。

db_host='localhost'
db_port='3306'
db_user='root'
db_password='yourpassword'
database='test_auto_new'

4. 邮件配置:修改 app/config.py 中关于邮件部分的配置(如不需要发送邮件,请忽略)。

# smtp 发送邮件相关配置:
is_email_enable = False #发送邮件开关
flask_host = 'http://localhost:5000' # 邮件中的报告链接会使用
smtp_server_host = 'smtp.163.com' # 如使用其他的smtp 服务,请修改对应host 和端口
smtp_server_port = '25'
smtp_from_email = 'youraccount@163.com' # 发送邮件的邮箱账号
smtp_default_to_email = 'youraccount@163.com' # 默认接收邮件的邮箱账号
smtp_server_user = smtp_from_email
smtp_server_password = 'yourpassword' # 发送邮件的邮箱密码

5 修改 app/config.py 中关于 atx server 配置(如不需要使用 atx 测试android 设备 ,请忽略):

# atx 配置
isUseATX=True
ATXHost = 'http://localhost:8000'

启动:

1.启动 flask:

python run.py 

此时可通过访问 localhost:5000 访问登录界面。
初始用户及密码: admin/0

2.1 启动 core service(selenium 的执行服务):

python core.py

2.2 启动atx core服务:

python atx_core.py
  • 基于atx 进行封装,从数据库中读取需要执行的测试用例,并转化、执行、记录测试结果及截图。
  • 需安装atxserver(https://github.com/openatx/atx-server),并修改 app/config.py 文件的以下内容:
# atx 配置
isUseATX=True # True 代表使用 atx
ATXHost = 'http://172.16.100.168:8002' # 对应的 atxserver 地址

3. selenium 接入(我目前是用docker 上面跑的selenium hub/node)

可以按以下两种方式进行接入:

3.1 selenium server接入:

  • 服务端启动:

    python run_service.py

    将通过9998 端口监听节点启动、关闭状态

  • selenium grid 节点启动: 将app/client 目录复制到已安装selenium driver 的服务器/PC 中,修改client.py文件中host 为服务端对应地址,并启动:

    python client.py

服务启动后,会启动 selenium server,并注册到服务器中。

3.2 其他方式(原有selenium server、selenium docker等)

附: docker 搭建selenium 镜像命令:

拉取相关镜像:

docker pull selenium/hub
docker pull selenium/node-chrome
docker pull selenium/node-firefox

启动 hub :

docker network create grid
docker run -d -p 4444:4444 --net grid --name selenium-hub selenium/hu

启动节点:

# 建议 NODE_MAX_INSTANCESNODE_MAX_SESSION 两个参数都设置为 10,便于并发执行
docker run -e NODE_MAX_INSTANCES=10 -e NODE_MAX_SESSION=10 -d --net grid -e HUB_HOST=selenium-hub selenium/node-firefox
docker run -e NODE_MAX_INSTANCES=10 -e NODE_MAX_SESSION=10 -d --net grid -e HUB_HOST=selenium-hub selenium/node-chrome

使用说明:

1. 新建用例:

用例步骤说明:

  • 每个用例步骤中通过逗号进行分隔。
  • 单个步骤的格式: 步骤名称+分隔符(|)+参数列表(参数间按@@进行分隔)。如:填写|id@@kw@@selenium, 表示步骤为“填写”,参数列表为“id、kw、selenium”。
  • 默认的参数含义:1:通过什么属性定位目标元素(可使用id、name、class、text、xpath、css等多种定位方式进行定位) 2:目标元素对应的属性值(如id = kw) 3:其他。
  • 例如:填写|id@@kw@@selenium: 代表通过 id = kw 查找到输入框,并输入 selenium 。

具体步骤说明请查看菜单:自动化测试-步骤说明。

用例说明:

例子:在百度中输入selenium,并验证查询结果是否正确。

Chrome,前往|http://www.baidu.com,填写|id@@kw@@selenium,点击|id@@su,验证|Web Browser Automation,截图

步骤解析:

- Chrome 调用 Chrome driver 进行测试。    
- 前往|http://www.baidu.com : 前往目标页。
- 填写|id@@kw@@selenium id kw 的元素中输入 selenium
- 点击|id@@su 点击 id su 的元素。
- 验证|Web Browser Automation 验证页面中是否出现 Web Browser Automation 的文字。
- 截图: 对当前页面进行截图并保存。

2.公共用例

某些公共的步骤,可以封装为公共方法进行调用:

  • 公共方法添加:新建用例,选择用例类型为 公共用例, 所属模块为public。
  • 公共方法调用:步骤: 公共方法|公共方法名, 如 公共方法|登录;公共方法|查询订单。

3.用例管理:

还可对用例进行如下管理:

  • 用例查询
  • 用例复制:新建用例时可考虑复制一条步骤类似的用例,再修改对应步骤。
  • 用例删除:逻辑删除,可在数据库对应表中恢复。
  • 用例执行:执行单条用例。可查看对应执行记录、截图、或重跑用例。

4.用例集管理:

  • 用例集(test suite)对应一个测试范围,可关联多个不同的用例。
  • 执行用例集时会根据设置的并发数进行并发执行,提高测试效率。
  • 用例集中的用例是从测试用例中复制而来,因此每个用例可以在多个不同的测试用例集中关联。
  • 用例集可重跑全部用例、重跑失败用例、重跑单条用例。 注意:重跑用例时,会自动从对应测试用例中加载最新的步骤。

5.节点管理:

  • 节点:可加载多个selenium grid节点,系统根据当前可用节点的数量,分配用例进行执行。

6.步骤管理:

  • 步骤:现已对大部分常见步骤进行了封装。
  • 扩展封装:可根据需要进行扩展封装。
  • - 可直接封装selenium的方法,请参考 刷新、前往、悬浮点击 等方法。
  • - 可对selenium提供的方法进行二次封装,请参考 点击、填写、选择等方法。对应扩展代码可在 app/core/extend.py 文件中进行管理。

update : 2018-08-24

新增android 设备使用 ATX 进行测试:

修改:

1. app/config.py 文件新增 ATXHost 配置,需要将 atx server 的地址配置到该项中

前提: 已安装 atx server进行设备管理

关于 ATX server:

请查看这篇文章的介绍:
https://testerhome.com/topics/11738

android 用例组织:

样例:
Android|com.your.packagename,点击|id@@com.your.packagename:id/btn_login,等待|2,点击|name@@GuestLogin,等待|5,截图,

已封装步骤:

相关的步骤已封装在 app/core/atx_step.py 中,具体包括:

Android : 打开指定已安装的app (通过包名)
填写: type_text
点击: click (by id/name/description/class)
截图: take_screenshot

由于我测试的 app 功能较为简单,目前只封装了这几个方法,如果需要可增加封装对应的方法。

update : 2018-08-28

新增测试用例编辑器功能

这个功能有助于提高用例的输入效率。 如下图示是如何添加一条《在百度搜索 testerhome 并截图》的例子:

效果如下:

update : 2018-09-19

新增在用例集执行完成后发送邮件进行通知的功能

需要在 app/config.py 文件中打开开关并配置对应的 smtp 账号、密码等信息

常见问题:

1:没有可用的节点

  • Q: 运行用例之后会提示这个-ERROR: no hubs is availabe!
  • A: 说明没有可以使用的selenium节点执行测试。请检查是否已启动对应的 selenium server,并已配置到节点管理中,而且服务器可以正常访问该节点。 ### 2:selenium 的浏览器被占用
  • Q:使用docker启动的selenium 镜像服务,如果用例执行报错, selenium grid console中的Chrome浏览器好像被置灰不可用了
  • A:这是因为如果执行报错时,没有正常退出 driver,导致对应的selenium线程持续被占用,需要等待一段时间才能释放。建议启动docker 的时候把最大进程设置为10, 这样可以并发执行,提高使用率: sudo docker run -e NODE_MAX_INSTANCES=10 -e NODE_MAX_SESSION=10 -d --net grid -e HUB_HOST=selenium-hub -v /dev/shm:/dev/shm selenium/node-firefox-debug

3:selenium 相关报错

  • Q:selenium相关报错
  • A:可能对应的 selenium server版本不支持目前使用的一些功能,建议更新到较新版本的 selenium server
共收到 154 条回复 时间 点赞

这个可以有,支持另外开发者上传代码吗

回复

欢迎提交到分支,合适的话我会抽空合并到主干

学习了,后期可以将macaca appium atx等兼容进来

peter 回复

我这边已经集成了appium 和 atx (之前集成的 macaca ,因为感觉不稳定,替换成了 appium 和 atx),不过这次整理的代码里没包括这块

想问下,存储在数据库中的关键字和对应的值是如何转化为可执行的测试用例的,例如appium所能执行的,看了下源码没太懂,代码能力较菜😂

枫叶 回复

读取关键字对应值:

调用:
keywords.keywords().getPara(keyword)

方法:
def getPara(self, keyword):
result = 0
log.log().logger.info(keyword)
sql = string.Template(
"select paraCount, template, elementTemplate from `test_keyword` where `keyword`= '$index' limit 1;")
sql = sql.substitute(index=keyword)
result = useDB.useDB().search(sql)
if len(result):
return result[0][0], result[0][1],result[0][2]
else:
return '','',''

转换为可执行语句:

调用:
conmod, element = self.convertToComend(template,paraCount,steps,elementTemplate)

通过对应的模板,传入对应参数后,转换为可执行命令。
转换有两种:

  1. 转换为直接可执行的 selenium 命令,如 填写方法, 对应的模板为: driver.find_element_by_$para1("$para2").send_keys("$para3")

当步骤中描述:
填写|id@@input_box@@ghw
转换为命令:
driver.find_element_by_id("input_box").send_keys("ghw")

  1. 对selenium 命令,封装成一些通用的方法。 如 选择方法,封装如下:

def select(self,driver,para_list):
method, value, option_method, option_value = para_list[0],para_list[1],para_list[2],para_list[3]
from selenium.webdriver.support.select import Select
if option_method =='index':
comd = 'Select(driver.find_element_by_%s("%s")).select_by_%s(%s)' %(method,value,option_method,option_value)
else:
if option_method == 'text_part':
self.select_by_visible_text(driver.find_element(by=method,value=value),option_value)
else:
if option_method == 'text':
option_method = 'visible_text'
comd = 'Select(driver.find_element_by_%s("%s")).select_by_%s("%s")' % (
method, value, option_method, option_value)
log.log().logger.info(comd)
exec(comd)
time.sleep(2)

模板:
extend.extend().select(driver,["$para1","$para2","$para3","$para4"])

步骤中描述:
选择|id@@selectBox@@index@@1
extend.extend().select(driver,["id","selectBox","index","1"])

Jerry li 回复

感谢,回复的如此详细,大概明白了

Jerry li 回复

什么时候开放集成appium和atx哈,期待。

问下哈,这边在本地部署好了,添加了测试用例,但是点击执行后就弹出提示,然后显示待执行是什么情况

  1. 是否已接入了可执行的 selenium 节点? 可以看下 自动化测试》节点管理 页面是否已有可用的节点。
  2. 是否已启动 app/core/coreservice.py 文件? 这是执行用例的核心服务,没有启动的话用例是不会执行的。
Jerry li 回复

好吧,这个是直接运行这个文件就好吧,自己添加了判断移动端的Appium框架的一些代码,目前看可以运行了,感谢哈😆

12楼 已删除
枫叶 回复

👍

update : 2018-08-24

新增android 设备使用 ATX 进行测试:

修改:

1. app/config.py 文件新增 ATXHost 配置,需要将 atx server 的地址配置到该项中

前提: 已安装 atx server进行设备管理

关于 ATX server:

请查看这篇文章的介绍:
https://testerhome.com/topics/11738

android 用例组织:

样例:
Android|com.your.packagename,点击|id@@com.your.packagename:id/btn_login,等待|2,点击|name@@GuestLogin,等待|5,截图,

已封装步骤:

相关的步骤已封装在 app/core/atx_step.py 中,具体包括:

Android : 打开指定已安装的app (通过包名)
填写: type_text
点击: click (by id/name/description/class)
截图: take_screenshot

由于我测试的 app 功能较为简单,目前只封装了这几个方法,如果需要可增加封装对应的方法。

已经很不错了,想知道下,执行任务那块是怎么做的呢,多线程吗??

思路不错,有时间研究下重构下

Aaron 回复

多线程读取数据库里的用例并执行

Jerry li 回复

嗯,谢谢。做得很好了😁

update : 2018-08-28

新增测试用例编辑器功能

效果如下:

Jerry li UI 自动化测试用例整理举例-百度首页 中提及了此贴 08月28日 19:56

请问下,已经运行了run.py&coreserver.py两个文件,但是运行的时候直接弹层提示了success,但是显示3-无法执行,请问这个是什么情况呢?
还有就是请问下,因为用的是docker里的selenium&Chrome,请问下添加节点里的ip和端口是填写selenium的还是Chrome的ip呢

已经在节点管理中添加了ip和端口,但是运行用例之后会提示这个-ERROR: no hubs is availabe!

舒克 回复

no hubs is availabe 就是没有可用的节点
你看下是否已经启动了对应的 selenium server , 并添加到 节点管理里面。

Jerry li 回复

已经在docker中启动了selenium-hub还有Chrome,而且把节点添加到了节点管理中,但是每次启动都是这个一样的报错😂

舒克 回复

看下 自动化测试》节点管理 页面的节点是否是打开状态:

舒克 回复

需要填写的是 selenium 的ip 和端口, 实际上就是通过类似的 selenium server 地址进行测试: http://XXX.XXX.XXX.XX:4444/grid/console

另外需要留意下docker 里的selenium 能否被你的脚本访问

Jerry li 回复


添加了这个节点而且状态也是开启的,但是不知道为什么出来了两个,而且运行用例后,一个节点的状态自动变成了关闭

舒克 回复

http://xxx.xxx.xxx.xx:4444/grid/console 看下你配的节点在部署的服务器上能否正常访问。 如果访问不了,服务器会认为这个节点已经关闭了,从而更新为已关闭。
如果是docker的, 看下如何开启docker 容器的网络权限到外网访问。

Jerry li 回复

单独运行这个程序,也是可以调用起docker里的Chrome 进行截图,但是用平台执行用例就会报错

舒克 回复

看下你本地的 app/core/buildCase.py 文件第 29 行是否有修改过? 你的代码和我GitHub 上的不一致:

github 上的代码:

你截图的代码:

Jerry li 回复


😂 代码重新更新了 一下,还是这个报错

舒克 回复

麻烦截一下完整的错误日志和你的用例

舒克 回复

而且当这个报错后,selenium grid console中的Chrome浏览器好像被置灰不可用了

舒克 回复

这是因为这个进程已经被占用掉了。
建议启动docker 的时候把最大进程设置为10, 这样可以并发执行,提高使用率:
sudo docker run -e NODE_MAX_INSTANCES=10 -e NODE_MAX_SESSION=10 -d --net grid -e HUB_HOST=selenium-hub -v /dev/shm:/dev/shm selenium/node-firefox-debug

Jerry li 回复



这个是报错的截图和用例,感谢您的回复

舒克 回复

检查下你的用例哦,少了步骤名称 “填写”
日志里也都有提示的:

Jerry li 回复

😂 终于找到原因了,感谢您;

现在我去找找怎么设置最大进程数应该就可以解决了

萌新请教一下,为啥我启动selenium服务的时候,会报错。。

夏顺斌 回复

你是在 ide 里运行吗?
这应该是python 的模块没有识别到,可以这样做:
方法1: 直接在 ide(如 pycharm) 里运行, 它会自动把当前目录加入到pythonpath 里面进行识别
方法2: 在 app 同级,新增一个 py 文件:

from app.core import coreservice

coreservice.coreservice()

然后直接运行这个文件,应该就没有这个问题

夏顺斌 回复

我已经在github上传了core.py 这个文件,用来启动coreservice.py服务

Jerry li 回复


为啥显示的执行结果是3-无法执行。。。

Jerry li · #42 · 2018年09月12日 作者
仅楼主可见
Jerry li 回复

大神。。最新的回复没权限看不见。。

夏顺斌 回复

看日志,没有可执行的节点,也就是没有可以用的selenium Server
不小心勾了仅楼主可见

Jerry li 回复

请教一下。。那我在服务端启动时,如何配置呢?

夏顺斌 回复

服务端? 服务器吗?

如果是 linux就写个 sh , Windows 就写个 bat 启动脚本就好

Jerry li 回复

额。就是启动server.py的时候。。提示没有可执行节点。。

夏顺斌 回复

看下这段,需要另外启动 selenium server,并且添加到节点管理里面。


大神,报这个错是啥意思?

夏顺斌 回复

截图看得不是很清晰,最好拿具体的错误信息去搜一下。
看起来应该是你的 selenium server 版本不兼容。

Jerry li 回复

是指和我的jdk版本不兼容吗??

夏顺斌 回复

selenium server 版本
你的selenium 节点是怎么启动的? java -jar selenium.xxx.jar 这种方式吗? 看下这个jar 包是什么版本的

为什么执行用例的时候,只提示sucess,然后并没有启动浏览器执行用例?

Z 回复

1、 core service是否已启动
2、 是否已启动可用的 selenium 节点

1、启动core service的时候提示 Process finished with exit code -1073741819 (0xC0000005) 不知道什么问题;
2、启动了这三个文件 run.py 、service.py 、client.py,算不算启动了可用的selenium节点?

Z 回复

把你的 core service 报错截图来看看?
另外说明一下几个文件的启动顺序:

  1. run.py : 这是启动 flask 的,也就是管理后台。
  2. core.py : 这是启动 core service 服务的,要执行用例一定要启动这个。
  3. service.py : 这是监听 client 服务的。
  4. client.py : 这是启动 selenium server 服务的。 如果已启动client, service 里会监听到并生成对应的节点。
Z · #58 · 2018年10月23日
仅楼主可见
Z 回复

可以加我 QQ 896745696

python client.py 提示错误: other system is not supported yet !

Halo 回复

你的是啥系统? 我好像暂时只写了支持 Windows

大佬,这个问题咋整~

威少 回复

win 10下的selenium环境问题吧,没遇到过,建议搜一下

Jerry li 回复

已经解决了,谢谢楼主!ChromeDriver没有被检测到
修改coredriver.py 的
driver = webdriver.remote.webdriver.WebDriver(command_executor=server_url,desired_capabilities=desired_caps_web)为driver = webdriver.Chrome()

我一直想做一个这平台,但一想到做,就觉得HTML,js,css基础不好,搞不定

Aaron 回复

其实用flask和bootstrap,基本不用涉及CSS,html 和js 也不难

作者您好。请问运行命令python run.py后登陆页面会提示请求出错是什么原因?

回复

回复

上次提交漏了提交配置文件,可以更新一下 autotest_platform/app/config.py 文件:

回复

原因是配置自动名字没同步,所以没连上数据库。 修改一下就好

Aaron 回复

后面再努力去实践一下,谢谢

Jerry li 回复

谢谢您😄

Jerry li 回复

请问调用公共用例怎么不能执行?单独运行是可以的

回复

看下你的公共用例名称是否正确

Jerry li 回复

公共用例名称是正确的。

回复

你的公共方法里是不是漏了 chrome 这一步?

Jerry li 回复

找到原因了,是因为我没把
Chrome删掉。。。

回复

👌 👌

android用例执行失败:


感谢大神,空闲时间帮忙指导一下。

RW_KING 回复

应该是之前的bug ,前几天做了优化没来得及提交。
麻烦更新以下几个文件试试看:

Jerry li 回复

感谢楼主,android的关键字方法,什么时候能与web的通用啊。

RW_KING 回复

应该是通用的格式啊,不过 android 我用的不多,所以对应的关键字封装的目前只有 点击、填写、截图、等待 等几个

Jerry li 回复

等待,提示元素没有定义

怎么同时跑多个设备呢

RW_KING 回复

出错的是 点击文字 , 这个方法我在 android 下是没封装的,可以用 点击|name@@XXX 来替代;

同时跑多个设备,需要先新建 测试用例集, 然后关联用例时选择需要执行的 设备列表, 然后再点击关联

Jerry li 回复


等待,执行失败

RW_KING 回复

格式错啦, 是 等待|5

Jerry li 回复

感谢😀 ;参数错位了

Jerry li 回复



楼主,打扰了。有2个问题想咨询下:
1、用例执行完,没有生成测试报告,也不可能发送邮件了,邮件配置如图
2、多个用例如何执行?是并发执行,还是按顺序执行呢?比如多个用例,前置操作都是登录,调用公共方法就OK吗

  1. 只有测试用例集(自动化测试》 test suite ) 执行完才会生成对应报告和发邮件, 否则每条用例执行都发一次邮件通知就太频繁了。
  2. 多个用例是并发执行的,每个都是独立执行。 即使调用同一个公共方法,也是分别独立调用的。

to 1. 只有测试用例集(自动化测试》 test suite ) 执行完才会生成对应报告和发邮件, 否则每条用例执行都发一次邮件通知就太频繁了。

  1. 多个用例是并发执行的,每个都是独立执行。 即使调用同一个公共方法,也是分别独立调用的。
RW_KING 回复

看上面的回复

收到,感谢楼主。

1、在尝试进行公司管理后台的用例编写,但是很多点击方法都没有成功,最后采用“前往”才进入‘用户管理’页面。
2、列表信息中,操作菜单内的功能按钮,关键字方法中,没找到具体定位方法

RW_KING 回复

我们的菜单也是类似这样的结构,我对应的解决方法是:

  1. 菜单: 新增一个自定义方法,用菜单文字+菜单特有的 class 属性进行定位。
  2. 右侧菜单栏: 类似的方法,文字+ 特有的 class 属性定位。

以上方案实在不行的话,可以考虑用 xpath 的相对路径定位。

Jerry li 回复

感谢解答,我去尝试下。

哈,巧合了。我是使用Java + springboot + Appium / Selenium,实现了一套类似功能的UI自动化测试平台。正在准备抽离业务代码做下开源分享,刚巧看到你的这篇帖子,学习一下。😀

2018-11-16 更新:

  1. 独立出 atxcore 任务,与 web ui 的 core 相互独立执行
  2. 优化 atx 步骤的封装

请问一下,点击登录之后
,报错误

数据表不存在,看下init.sql 的数据是否已经导入到你的数据库里面

数据表不存在,看下init.sql 的数据是否已经导入到你的数据库里面。

Jerry li 回复

对对,下午的时候没仔细看,直接来问,后来解决了忘记回来删除,麻烦麻烦!!!

simple 专栏文章:[精华帖] 社区历年精华帖分类归总 中提及了此贴 12月13日 14:44

图片上传和弹出浮层的选择框用什么方法,我试了一下,好像都不能用

stefan 回复

图片上传如果是input类型,可以试下 填写文件 方法
弹框的选择看是什么类型,如果是 select 也可以用 选择 方法

Jerry li 专栏文章:一个测试平台的构思、搭建到完善 中提及了此贴 12月27日 11:02

大神我想问一下,我想在您的平台里实现,读取页面中指定元素的文字并写入到一个文本框里,可以实现么,我试了试改步骤,总是不行

Rladmsrl 回复

刚刚做了一个简单的实现,添加了一个复制方法:
复制: 将某个元素的内容(value、text、innertext)复制填写到另一个元素中。
刚刚已经提交到最新代码里了,可以更新下来看看。

  1. 更新 app/core/extend.py 文件
  2. 更新 init.sql, 执行最后新增的sql
  3. 使用: 分别定位两个元素,获取后一个元素的值,并填入到前一个元素中。 如:复制|id@@kw@@id@@su: 定位 id = su 的元素,获取元素的文字, 并写入到 id=kw 的元素中。 insert into `test_keyword` ( `keyword`, `paraCount`, `template`, `elementTemplate`, `example`, `description`, `status`) values('复制','4','extend.extend().copy_from_another_element(driver,[\"$para1\",\"$para2\"],[\"$para3\",\"$para4\"])','driver.element_by_$para1(\"$para2\")','复制|id@@kw@@id@@su','将后一个元素的内容复制填入到前一个元素中','1');
Jerry li 回复

更新后之前的用例为啥都不见了 而且跑case的时候提示 failed to change window state to normal, current state is maximized

Jerry li 回复

还有一个问题我想问一下,怎么才能把平台里设计的用例备份或者导出一下,省的我一不小心弄错东西用例又白做了,谢谢您了

Rladmsrl 回复

你是重新初始化了数据库吗? 或者看下 app/config.py 文件是否覆盖了,导致没连上数据库

Rladmsrl 回复

备份可以直接在数据库里做

Jerry li 回复

搞定了大神,我把mysql重启了一下然后重新执行了一下init.sql就好了,但是我又发现一个问题,执行init.sql会覆盖case和节点数据吗?那我下次在更新的时候要怎么操作才能在不丢失数据的情况下升级,谢谢啦

Rladmsrl 回复

init sql 是在初始化的时候才要做的,如果你已经初始化过,就不要轻易去执行了,否则可能把你原来的数据给清掉
可以对比下你的版本和最新的版本,看新增了什么 sql 语句需要执行的

Jerry li 回复

好的谢谢您了

楼主是怎么实现web端通过关键字编辑用例,然后在手机真机上运行的?卡在这里很久了,因为之前我是C/S结构

乱斗东 回复

你用的什么框架来测试手机端? appium 吗?
其实原理一样,把关键字转换成对应框架的命令就可以了

Jerry li 回复

对,用的是appium框架,就是web端怎么和Android设备通信是目前遇到的一个问题

乱斗东 回复

我是用的 atx server,通过 wifi 无线连接手机进行测试。
appnium 的话可以搜一下论坛里的帖子,之前看到有人分享过怎么进行管理

Jerry li 回复

好的,谢谢!


我发现使用填写文件的时候,会自动把\去掉。这个怎么解决。去掉了\导致了路径不正确

stefan 回复

试下两个\

请问能同时运行多个任务么? 如果有不同的环境需要同时跑自动化,那么这些任务是怎么组织和分发?

Aaron 回复

所有的任务都是转换为单条测试用例进行管理的。
例如分别有A、B、C 三个任务,分别有100条用例,那么定时任务就会查到有300条用例待执行,自动按设定的并发数(默认为 6 )并发执行。

124楼 已删除
仅楼主可见
Aaron 回复

每个任务生成独立的报告

Jerry li 回复

知道了,谢谢

Jerry li 回复

两个//也不行

stefan 回复

两个 \ 还是 / ?

Jerry li 回复

两个\

stefan 回复

新提交了一个修改,应该可以兼容 \ 了。 这是 python 的转译符,默认保存的时候会转换掉

init.sql无法执行怎么办,好像是版本不支持

初学者 回复

试下把这行注释掉,然后手动建库 test_auto_new,再执行 init

Jerry li 回复

谢谢楼主大大

simple [精彩盘点] TesterHome 社区 2018年 度精华帖 中提及了此贴 01月07日 12:08

这个上传文件的还是搞不定啊。同样的一句上传文件。我单独放在一个Python文件里面就能执行成功,但是在你这个里面。文件就上传不了。不知道什么原因。 driver.find_element_by_xpath("/html/body/div[2]/div/div[2]/div/div[1]/div[2]/form/div[3]/div[2]/div/span/span/div[1]/span/input").send_keys("I:\3333.jpg")
就是这一句

stefan 回复

试下用 填写文件 方法,不要用 填写1

stefan 回复

另外你的这个xpath 很长,可以的话建议用其他定位方式来替代,比如 id 、class 等

Jerry li 回复

都试了。都不行。换成短的也试了。也不行。

stefan 回复

我这边是没问题的,如果你本地用 selenium 可以执行,可以检查一下:

  1. 是否同一台设备?
  2. 图片在平台运行的服务器或者PC 上是否存在?
  3. 文件路径是否完全一致?
  4. 本地的 selenium 和平台调用的 selenium 是否同一个版本?

填写 方法就是按 driver.find_element_by_xpath("/html/body/div[2]/div/div[2]/div/div[1]/div[2]/form/div[3]/div[2]/div/span/span/div[1]/span/input").send_keys("I:\3333.jpg") 这种格式进行封装的,所以如果selenium 直接运行ok ,理论上这样调用也没问题

Jerry li 回复

嗯嗯,谢谢楼主。我自己再调试看看。谢谢

Jerry li 回复

终于成功了。路径前面要加个r如果不加,就会被转义掉。
只能暂时这么特殊处理了


老哥,请教个问题
这个是你test_case的编辑,你可以通过用例id直接查找,然后跳转到edit_test_cases2,而且有着数据
但是我自己也写了一个编辑,用着新的数据库,我也可以进行跳转,但是没有数据是什么原因?

luomomimi 回复

从后台获取用例的完整信息,是在 js 里实现的

html 里的调用:

<script>window.onload =function(){document.getElementById('btn_reset').click();}</script>

对应的 js :
/static/scripts/core/test_case.js

// 编辑表单
function get_edit_info(active_id)
{
if(!active_id)
{
alert('Error!');
return false;
}

$.ajax(
{
url: "/test_case.json",
data:{"id":active_id,"type":"test_case"},
type: "get",
dataType:"json",
beforeSend:function()
{
return true;
},
success:function(data)
{
if(data)
{
// 解析json数据
var data = data;
var data_obj = data.rows

// 赋值
$("#id").val(active_id);
$("#name").val(data_obj.name);
$("#steps").val(data_obj.steps);
$("#description").val(data_obj.description);
$("#type").val(data_obj.isPublic);
var isPublic = data_obj.isPublic;
if(isPublic == 1)
{
$("#type").val('公共用例');
setModule('公共用例');
}else{
$("#type").val('普通用例');
setModule('普通用例');
}
$("#module").val(data_obj.module);
}

else
{
$("#tip").html("<span style='color:red'>失败,请重试</span>");
// alert('操作失败');
}
},
error:function()
{
alert('请求出错');
},
complete:function()
{
// $('#tips').hide();
}
});

return false;
}

Jerry li 回复

还是不行,真的很奇怪!

仅楼主可见
luomomimi 回复

看下你的js 是不是成功调用了
具体可以参考下我原来的 html 写法

刚开始就是模仿你的,js文件里面就是将test_case换成了test_app ,然后新建了一个新的数据库,其他没改动过,这应该调用成功了吧

luomomimi 回复

F12 跟踪一下看下请求有没发送,还有参数是否正确

Jerry li 回复

改成test_app,解决了,真的难受。。谷歌浏览器的缓存好坑,但是编辑里面的赋值还是没有解决,我只能找到id,然后。。。然后就没有软后了

luomomimi 回复
  1. 你的查询接口有返回这些对应数据吗?
  2. js 里有把这些返回值赋值给对应的参数吗?
  3. 另外我原来的html 里有个 script,是要页面加载时自动点击一下 reset 按钮,调用 get edit info 接口来查数据,你看下新的页面里有没加这个。
Jerry li 回复

全部是用你的,我就是改了名字而已(里面的方法名也都改了),但就是不显示;我也查看了你test_case的搜索方法,但和你一样呀,你也只查询了id而已,但网页最后有数据。
js里面的赋值应该没多大关系,我都是默认的,但用例名称也不显示
htm的reset按钮有的,网页也和你一样,但是也没有数据,只有id

luomomimi 回复

一步步排查吧:

  1. js 方法有没触发。 可以在 js 里打印 log 来跟踪。
  2. 接口有没调用成功。 看 F12 - 网络下的请求记录和返回值。
  3. 2.1 如果有返回值,就看js 处理是否成功,有没成功赋值、返回值格式是否正确;
  4. 2.2 如果没有返回值,看 view 里的对应方法处理是否正确
Jerry li 回复

JS打印日志过了,触发了
接口调用成功,debug模式有id传进来
但问题就是只传了id,我用了你原来的文件,讲道理modle和名称起码应该可以和id一起传进来,但现在都没有。
老哥,现在有空么,能帮我查看下么

luomomimi 回复

可以加我 QQ 896745696

楼主,各种弹框,页面,ifame的切换,你这里怎么设计的?

都是封装selenium 的方法处理,例如:

def switchIframe(self,driver,para_list):
method, value = para_list[0], para_list[1]
# 切换 iframe
if method=='css':
method = By.CSS_SELECTOR
driver.switch_to_frame(driver.find_element(by = method,value=value))
time.sleep(2)

def switchWindow(self,driver):
for name in driver.window_handles:
if name != driver.current_window_handle:
driver.switch_to.window(name)
time.sleep(2)

Jerry li 回复

最近我也在做这方面内容,和你差不多也是这样维护的,发现用例维护进来的错误率太高了,最后本地搞了个简单的测试脚本...

大神,想问下 这里面接口这部分是怎么操作的呢?

指的接口测试部分吗? 现在接口测试没有放在这个平台上面

Jerry li 回复

有放在这个平台的意向吗?

内部使用有集成的,不过效果不是很好,后来改成单独的接口测试项目进行管理了

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册