听过自动化测试、自动化操作,怎么还有自动化开发?而且还是C++的代码?
本文介绍了在 Qt Creator 这个 IDE 的界面自动化完成一个Qt应用的开发,包括项目配置与编译运行,从而介绍 Linux 的界面自动化中可能遇到的问题以及解决方法。Windows的界面自动化也可以如法炮制噢。
使用到的工具和环境如下:
工具
Qt Creator (Qt 4.8/5.7 以上)
CukeTest 1.6.0 以上
环境
银河麒麟 、UOS(或 Ubuntu 16.04 以上)
自动化流程
在大多数 IDE 中,完成一个项目开发的过程都是类似的,即以下几个步骤:
创建(Create)
配置(Configure)
编辑(Edit)
构建(Build)
运行(Run)
因此在自动化 Qt Creator 开发的时候也按照上面的过程来组织自动化流程。在 CukeTest 中新建完项目后(注意选择模板以方便完成界面自动化),根据 Qt Creator 的界面,可以先编写Cucumber的剧本文件,这也是BDD 开发的第一步。
由于 Qt Creator 的项目构建和运行比较简单因此直接放在同一个场景中。代码编辑部分借助了场景大纲的功能,将已有的代码文件内容写到项目中。
编写脚本
为了方便介绍在编写 Linux 界面自动化的过程中经常会遇见的奇怪的坑,以及如何规避这些坑,本次演练不同于以往先识别完全部模型再编写脚本的方式,采取边编写脚本边根据需求识别模型的方式来完成项目。
第一个场景:创建项目
第一个场景的只有一个步骤,如下:
选择新建项目
在 Qt Creator 中,创建项目跟项目配置都是在同一个配置向导中完成的,但是由于项目配置的场景可能会比较复杂,所以还是将创建项目单独的划分为一个场景。
1. 选择新建项目
观察界面,可以很快的注意到创建项目需要以下几个操作:
创建项目
首先定位到“欢迎”页面,接着选择“项目”标签页,最后点击“新项目”按钮就可以创建一个新项目。但这里我们选择了另一种取巧的办法——通过菜单来创建项目。打开菜单就可以看到新建项目的选项:
“新建项目”菜单项
所以只要识别菜单中的“新建项目”选项,就可以操作它完成项目的创建了。双击项目中的模型文件(后缀名文件)打开模型管理器,接着选择菜单中的“操作”“启动 Qt 应用”重新打开 Qt Creator。注意,这一步很重要,CukeTest 通过这种方式在应用内部注册了监听,才可以顺利完成下一步侦测。
打开工具栏中的“侦测”按钮,可以看到 Qt Creator 中的菜单栏已经可以高亮了,那么问题来了,要怎么展开菜单呢?在侦测过程中只要按住键就可以暂时退出鼠标侦测模式,变为正常的鼠标点击,点击菜单展开以后再松开键继续识别。
点按菜单项时,可以适当的按住一段时间直到侦测窗口弹出,这样可以识别到完整的窗口模型。因为有些菜单在点击后会消失,可能会导致模型管理器侦测到的模型出现偏差,长按保证在菜单不消失的前提下完成侦测。
识别到的结果和属性如下:
“新建项目”菜单项侦测结果
“新建项目”菜单项的对象属性
接着编写脚本,由于菜单项提供了一个直接操作的方法——,可以不用展开菜单直接触发目标菜单项,因此脚本非常简单,写作如下:
场景的演示如下:
第一个场景演示新建 hook.js 文件减少调试操作
在编写脚本的过程中免不了反复的调试,新建一个文件,在其中配置好执行自动化前的准备工作、运行后的清理工作,就可以专注于调试了。在本个项目中,准备工作也并不多,有如下:
运行前
启动 Qt Creator
启动后最大化
运行后
最大化 CukeTest
在目录下新建文件,因为需要最大化 Qt Creator,因此需要侦测添加它的窗口,这里将窗口控件命名为。与是 CukeTest (也是Cucumber)提供的Hook函数,可以从工具箱中拖拽到代码编辑器中来调用。
脚本文件内容如下:
在这一步中我们还使用了每个控件都有的方法——,它的作用是在指定的延时(单位为秒)内检查控件是否存在,如果存在则返回,超时则返回。这里就是通过检查被测应用的窗口是否存在,来判断被测应用是否成功启动。
通过这种方式来等待目标控件出现,相比于延时等待固定时长来说,要更加可靠跟省时。
第二个场景:配置项目
完成第一个场景后,我们就可以接着进行下一个场景的编写了。在这个场景中,我们需要配置项目的模版,并确定项目名与项目保存路径。步骤如下:
使用项目默认模版
项目名为"AutoCode"
项目保存到"$HOME/"文件夹下
其它配置保持默认
为了简化过程,这里的配置采用了常用的默认配置,感兴趣的同学可以试着写出一组可以灵活配置的步骤。
1. 使用项目默认模板
在这个步骤中需要选择项目采用的模板,如下:
项目模板
所以只要识别到右下角的“Choose...”按钮,就能按照默认的模板选项进入下一步了。识别到该按钮后,脚本写作如下:
如果默认的模版不为,那么在进入下一步前应该先切换为,就像脚本第一行那样。
2. 项目名为"AutoCode" & 3. 项目保存到当前文件夹下
第二步就是为项目命名,这里将项目名用英文双引号包裹起来的目的是将其格式化为一个字符串参数,这样就可以通过修改双引号中的内容来控制项目命名了。
这一步接着上一步选择完项目模版后的配置,界面如下:
项目名称与保存路径
第一个输入框决定项目的名称;第二个输入框决定项目的保存路径,那么在这个界面中我们就可以完成 2 和 3 两个步骤,脚本如下:
在完成修改后点击右下角的“下一步”按钮。点击完需要加一段时间的延时,原因的话我们会在下一个步骤中揭晓。
4. 其它配置保持默认
剩下的配置全部保持默认的话,只需要一路的点击“下一步”按钮即可,如下图所示:
其它配置1
其它配置2
其它配置3
并且由于这些“下一步”按钮的属性完全一致,识别到模型管理器中也会被合并处理。接着这个时候如果按照常规的方式去编写脚本,应该是写成如下所示:
这里我们将“下一步”按钮的对象名称改为了以便于调用
如果这样编写脚本,运行时会出现一个问题,那就是页面的响应速度远低于脚本执行速度引起的:
当执行方法时,CukeTest 会向被操作应用中的目标控件发送一个点击信号,这个异步操作就算是完成了;
接着便开始执行下一行脚本,同样也是方法,因此同样的发送了信号,但是此时界面还没有跳转到下一页,因此两次点击信号会发送到同一个按钮上,导致丢失了一次点击,接着就会引起错误。
为了避免以上问题,需要手动的在点击的执行间隔加入短暂延时来保证页面有足够的时间更新。
第二处延时本来是非必要的,因为 CukeTest 中的所有控件方法都会主动的重试直到目标出现后进行操作,与方法类似。但是这个“完成”按钮,在其它的页面中也存在,但是被设为不可见和不可点击的状态,这就导致了如果不设置该延时,会直接对本页面中某处不可见的按钮发送点击信号,从而导致操作丢失。
场景的演示如下:
第二个场景演示第三个场景:编辑项目
接着是编辑项目,这里将操作简化为从指定编辑好的文件中读取内容再写入到 Qt Creator 的编辑器中。由于这次使用的不是普通的场景,而是场景大纲,在场景大纲中,每一行数据都会被格式化到步骤中,形成一个个独立的场景。因此需要保证每个场景都是完整的、可以被单独执行的。
如果没有数据则不会生成任何场景,也不会被执行。
进入编辑界面
读取""文件内容
打开""文件
写入到文件中
1. 进入编辑界面
虽然创建完项目后会自动进入到编辑界面,但是为了保证场景是完整且能够独立运行的,应该要将“进入编辑界面”这一步骤加入。实现方式是点击左侧导航栏中的“编辑”按钮进入编辑界面。(如下图红框所示)
导航栏信息
但是在识别按钮的时候会发现,这个“编辑”按钮是一个绘制出来的控件,无法被识别到。这个时候就要使用虚拟控件来解决了。
首先,识别“编辑”按钮所在的父控件:
左侧导航栏
由于界面会根据当前打开的文件名切换窗口标题,而窗口标题是作为控件的识别属性之一,所以在添加时需要把窗口中的属性的勾选去除。后续的侦测操作都要注意这一点,因为大部分控件的根节点都是应用的主窗口,因此保证主窗口能够识别到是非常重要的。
窗口标题根据当前打开的文件变化
窗口的属性之一——标题
接着,在识别的控件中编辑虚拟控件:
添加虚拟控件
为了清楚的描述控件,这里将上一步中识别的控件名改为了,代表导航栏。
最后,添加虚拟控件并框选出“编辑”按钮所在的位置,并为虚拟控件取名为:
接着编写脚本,只需要点击该按钮就可以跳转到编辑界面了。
Qt Creator 的编辑器可以同时打开多个文件的编辑界面,为了避免错误的写入,我们在每次切换到编辑界面的时候手动的将编辑器中已打开的文件关闭。
关闭文件2. 读取""文件内容
读取文件需要使用到 NodeJS 提供的文件读写库库与文件路径操作库库,因此在编写前在 js 文件最顶部加上这两行引用:
因为使用到了示例表中的数据,这里回顾一下示例表的内容,步骤中的表头名会格式化到步骤的相应位置:
示例表
接着将传进来的文件路径与当前路径拼接后,读取该文件:
这个场景没有涉及到界面操作。使用了关键字来在场景中传递参数。
3. 打开""文件
打开目标文件的方式很简单,在左侧的项目文件树中找到目标文件,再双击打开即可。需要使用到 CukeTest 针对树组件提供的查找树节点的方法——。
首先当然还是识别项目文件树:
侦测文件树
没有默认勾选的节点大多为容器节点,勾选上这些节点可以调整控件识别的准确度,但是相应的会付出一定的识别速度的代价。大部分情况下保持默认即可。
编写脚本:
4. 写入到文件中
由于目标文件已经在编辑器中打开,因此只要写入到编辑器中,并保存即可修改到文件中。所以需要识别编辑器与菜单中的”保存“按钮。
识别操作上面已经进行过很多次了这里就不演示了,识别完编辑器与”保存“菜单项两个控件后,编写脚本如下:
场景的演示如下:
第三个场景演示最后一个场景: 构建与运行项目
最后一个场景非常简单,如果希望使用默认的构建套件构建,只需要直接触发菜单中的”运行“项即可。但是这里加上了切换构建套件以及验证是否成功运行的步骤。
切换"Release"版
构建并运行项目
验证项目成功运行
1. 切换"Release"版
点开左下角的构建套件选择按钮,并选中目标套件即可。由于切换套件的界面本质上是两个列表,因此只要使用 CukeTest 为列表组件提供的查询方法——即可,用法与第三个场景第 3 步中查询文件树的用法类似。
识别到构建套件选择按钮和列表后,编写脚本如下:
2. 构建并运行项目
识别菜单中的”运行“按钮。
菜单中的”运行“按钮
脚本非常简单:
3. 验证项目成功运行
最后是验证项目是否成功运行,首先让我们看看项目预期运行的结果:
运行结果
项目生成了一个简单应用,因为也是 Qt 应用,并且是由 Qt Creator 派生出来的 Qt 应用,因此可以被 CukeTest 直接识别到。因此我们通过侦测这个应用的控件,并用方法判断该应用的控件是否存在、内容是否一致,来验证项目是否成功。
因为需要验证内容,所以就需要引用 NodeJS 提供的断言库——库,在文件顶部引入如下文件:
在识别应用中的消息框(即内容为”HELLO WORLD!“的控件)后,编写脚本如下:
场景的演示如下:
第四个场景演示总结
这里介绍的是Linux平台的桌面自动化,使用类似的工具或方法,你也可以做Windows平台上的自动化开发,例如操作Visual Studio等工具。通过操作这些开发工具,自动生成应用。虽然不通过界面自动化的方式,而是通过命令行的方式也可能可以生成您的应用,但这样做是不是更cool一点呢。
领取专属 10元无门槛券
私享最新 技术干货