一、 用例函数之 init() 和 cleanup()
附加模式下 一定要注意用例结束后的恢复工作,否则会造成后续用例失败;
squish中默认提供了init和cleanup函数:
init()方法失败,main()方法不执行,cleanup()方法会执行; main()方法失败,cleanup()方法会执行;由此可见,无论初始化和main函数是否成功,cleanup()都会执行;所以如果cleanup的操作是清理测试过程中产生的数据,而init和main很可能根本不会生成数据成功,cleanup的实现就需要兼容;
我建议采用数据库清理、界面刷新操作来保障;
二、数据库连接
对于squish6.3内置python2.7而言,安装python三方库着实废一些功夫;
1、pgsql连接
尝试使用pg8000库:
tar-xzvf pg8000-1.10.5.tar.gz cd pg8000-1.10.5/cp-r pg8000-1.10.5/pg8000{squish安装目录}/python/lib/python2.7/site-packages# 根据运行case报错问题,拷贝_hashlib.socd{squish安装目录}/python/lib/python2.7/lib-dynload cp/usr/lib64/python2.7/lib-dynload/_hashlib.so./# 根据运行case报错问题,拷贝sixcd{squish安装目录}/python/lib/python2.7/site-packages cp/usr/lib/python2.7/site-packages/six.py./cp/usr/lib/python2.7/site-packages/six.pyc./运行case,提示Fail Authentication method 10 not recognized by pg8000.
是因为 pg8000 驱动版本太旧,不支持 PostgreSQL 14 默认的 scram-sha-256 (认证代码10) 认证方式。AI要我升级 pg8000 1.16.5 或 1.15.3,但注意,> 1.13.0 版本,pg8000 不支持 Python 2.7,遂放弃。
尝试使用psycopg2库:
psycopg2_binary-2.8.6-cp27-cp27mu-manylinux1_x86_64.whl#官网下载psycopg2-binary包unzip psycopg2_binary-2.8.6-cp27-cp27mu-manylinux1_x86_64.whl-d'解压目录'cp 目录名/*{squish安装目录}/python/lib/python2.7/site-packages/运行case,依然提示Fail Authentication method 10的错误,从psycopg2.7.5-》psycopg2.8.0-》psycopg2.8.6都是这个错误,最终通过修改pgsql服务器配置解决;(并不是所有项目都允许修改这个配置,有条件还是升级python版本)
数据库服务端修改配置:
ALTER SYSTEM SET password_encryption='md5';SELECT pg_reload_conf();ALTER ROLE{你的用户名}WITH PASSWORD'密码';SELECT pg_reload_conf();# -*- coding: utf-8 -*-importpsycopg2 test.log(str(psycopg2.__file__))#{squish安装目录}/python/lib/python2.7/site-packages/psycopg2/__init__.pyctest.log(str(psycopg2.__version__))# 2.8.6test.log(str(psycopg2.__libpq_version__))# 110005test.log('psycopg2 import succ')defmain():conn=Nonecursor=Nonetry:conn=psycopg2.connect(host='xxx',port=5432,database='db',user='user',password='password')cursor=conn.cursor()cursor.execute("select * from Table where Field = '100027'")results=cursor.fetchall()test.log('succ')test.log(str(results))exceptExceptionase:test.fail(str(e))finally:ifcursor:cursor.close()ifconn:conn.close()# 如果运行报错找不到库文件,就把上面的解压包中的libs目录添加到LD_LIBRARY_PATH中: export LD_LIBRARY_PATH={解压目录}/psycopg2_binary.libs:$LD_LIBRARY_PATH2、oracle连接
cx_Oracle-7.3.0-cp27-cp27mu-manylinux1_x86_64.wfl # 官网下载这个包,改为.zip,将解压后的cx_Oracle.so拷贝到{squish安装目录}/python/lib/python2.7/site-packages/ # 此外,还需下载oracle 11g对应的Instant Client,不再赘述;# -*- coding: utf-8 -*-importcx_Oracle test.log(str(cx_Oracle.clientversion()))# (11, 2, 0, 2, 0)defmain():dsn=cx_Oracle.makedsn(ip,port,service_name={database})connection=cx_Oracle.connect(user,password,dsn)cursor=connection.cursor()cursor.execute(xxx)results=cursor.fetchall()test.log('succ')test.log(str(results))cursor.close()connection.close()三、公共方法
1、全局
window-Show View-Other-Squish Test-Global Scripts,创建全局脚本目录,创建全局python文件;
可以将数据库连接这种各个测试套都需要共享的方法写入global scripts中,在testcase文件中顶部引入,就可以直接使用python文件中的方法或类了。
source(findFile("scripts","base_method.py"))2、测试套内
测试套目录下,可以mkdir -p shared/scripts创建shared目录,这样在ide中创建python文件时,会自动生成在此,用于封装一些测试套内公用的方法;
source(findFile("scripts","widget.py"))四、问题定位
记录刚编写自动化代码时遇到的小问题,如果能给大家带来帮助和思路,就很不错了~~
问题一
测试中遇到一个表格控件的表头怎么右击都无法弹出右键菜单;
# 程序代码horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu);verticalHeader()->setContextMenuPolicy(Qt::CustomContextMenu);connect(verticalHeader(),SIGNAL(customContextMenuRequested(const QPoint&)),this,SL0T(ExecContextMenuVHeaderView(const QPoint&)));父级:{container=':PaiWindow_PunitParameterEditView'orientation='1'type='QHeaderView'unnamed='1'visible='1'}内层:{container=':_QHeaderView'text='PUNIT'type='HeaderViewItem'visible='true'}自动录制的代码中,控件使用的是内层HeaderViewItem,一直不生效,尝试换成QHeaderView;
# 方式1openContextMenu(waitForObject(":_QHeaderView"),200,10,0)# 失败# 方式2mouseClick(waitForObject(":_QHeaderView"),200,10,0,Qt.RightButton)# 失败# 方式3(坐标位置都是正确的)obj=waitForObject(":_QHeaderView")sendEvent("QContextMenuEvent",waitForObject(":_QHeaderView"),0,400,10,0)# 失败# 方式4center=get_center_point(waitForObject(":_QHeaderView"))nativeMouseClick(center.x-300,center.y,Qt.RightButton)# 失败# 方式5 MouseButton也失败,改为Qt.RightButton成功nativeMouseClick(waitForObject(":_QHeaderView"),200,10,0,Qt.RightButton)# 成功方式4是把坐标交给操作系统后,事件落到哪个窗口,Squish 控制不了。它只是“在屏幕这个点按了一下右键”,至于这一下被谁接住,取决于当时屏幕上那个位置最顶层的窗口是谁。
而方式5参数形式,Squish 知道目标是 _QHeaderView,它会确保事件最终作用到这个控件上。
问题二
一个QTableWidget下有多个QModelIndex,我需要鼠标左键按下滑动选择多个QModelIndex,一开始我从QModelIndex单击开始,使用mouseDrag方法滑动选择区域,但是无论参数怎么填写,依然报重载问题,错误如下:
Detail SyntaxError: Ambiguous overload 'mouseDrag(Object, int, int, int, int, int, int)'. Candidates: Squish::Global::mouseDrag(QWidget * source, int x, int y, int dx, int dy, int state, Qt::MouseButton button) Squish::Global::mouseDrag(char * object, int x, int y, int dx, int dy, int modifiers, Qt::MouseButton button) Squish::Global::mouseDrag(QQuickItem * object, int x, int y, int dx, int dy, int modifiers, Qt::MouseButton button) Squish::Global::mouseDrag(QWindow * object, int x, int y, int dx, int dy, int modifiers, Qt::MouseButton button)Ambiguous overload 这个错误,根源在于函数重载时无法区分用哪个。QModelIndex 本身不是任何控件(QWidget),不占据屏幕空间,也不接收鼠标事件。把一个 QModelIndex 类型的对象传进去,Squish 底层无法完成类型转换。所以要模拟鼠标拖拽,必须直接对 QTableWidget 控件本身进行操作,因为只有它才是一个真实的、可交互的 QWidget。
✅ 正确路径:操作其容器 QTableWidget
item=waitForObject("{container='xxx' type='QTableWidget' unnamed='1' visible='1'}")mouseDrag(item,52,280,0,60,0,Qt.LeftButton)# 52,280是控件内部开始拖拽的相对坐标;0,60,是滑动的相对坐标;通过以上2个例子可见,调用操作方法时,使用哪种type类型的控件去操作很重要!!!如果一直行不通,可尝试返回上一级的控件去操作,而且有些属性也是需要上一层才能获取,或者操作行为上变通下。