分享好友 资讯首页 频道列表

代码测试中的Python应用1 | VectorCAST单元测试报告自定义需求的GUI开发

2021-03-08 15:19
在配合主机厂审核VectorCAST/C++单元测试报告的过程中,某用户提出了一系列针对报告生成的需求:自动获取工程项目中所有被测环境的完整报告,可自定义报告显示的名项(如截除源码)并创建索引,适配其持续集成测试系统等。
 
鉴于该用户在Linux操作系统下测试,且多以命令行调用方式执行,因此我们应用Python为其开发了定制化脚本,快速交付后完成了用户的成功上线。
 
随后,在Windows系统下测试的某新用户也提出类似需求,对原Python脚本进行重构及添加GUI(Graphical User Interface,图形化的用户界面)调用方式的解决方案也应“需”而生。
图 1 图形化用户界面
 
Part 1
GUI库的选择
Python的GUI库包括自带的Tkinter,以及第三方库PyQt、PySide等,那应该选择哪款呢?
下表是三种GUI库在安装方式和商用情况上的对比:
库名
是否需单独安装
商用情况
PyQt
闭源商用须付费
PySide
闭源商用可免费
Tkinter
闭源商用免费
表 1 三款GUI库对比
从表1可看出:
>
PyQt虽然功能强大、支持完善,但其遵循的GPLv3协议要求闭源商用时有付费许可证;额外的采购流程无法满足快速交付的需求
>
PySide,尤其是PySide2在功能实现上可比肩PyQt,且其采用LGPL协议支持闭源商用;但需单独安装,对外网连接受控的用户不友好,不利于后续的维护;
>
Tkinter则是Python自带的GUI库;而且VectorCAST内嵌了一个vpython工具,是对Python进行封装,可用来直接执行调用Tkinter库的脚本程序。
综合考量后,我们选择使用Tkinter进行该需求的开发。
 
Part 2
GUI设计和实现
GUI模块的设计通常包含元素的布局和元素的创建。为了方便后续的扩展维护,在原脚本程序的基础上,对UI元素的创建过程进行了封装,形成一个独立的界面元素封装模块UI_Element。在GUI模块中规划好元素布局后,通过调用UI_Element模块提供的接口即可高效地完成程序代码的实现。
图 2 重构和封装GUI元素
这种设计方式降低了GUI模块和界面元素模块之间的耦合度,模块内部则是高内聚的,程序结构也更加清晰,同时还有以下好处:
>
两个模块各自的维护可以做到互不影响,可维护性高;
>
程序后期扩展时,可方便增减界面元素或重新布局;
>
两个模块都可直接复用于新项目中。
通过以上一系列对原脚本模块的拆分和二次封装后,程序分成了四个部分:
  1. Core:业务逻辑模块,通过调用VectorCAST/C++提供的功能接口,生成报告和索引;
  2. CLI:命令行调用模块,通过命令行方式使用程序的入口;
  3. UI_Element:界面元素封装模块;
  4. GUI:图形界面用户模块,通过GUI方式操作此程序的入口。
图 3 程序模块的调用框架
 
本文简要介绍UI_Element模块和GUI模块,Core模块和CLI模块将会在后续文章中陆续介绍。
 
// UI_Element模块
该模块封装了当前程序中各种界面元素的创建过程,包括菜单、标签、按键、文本框、组合框、状态栏以及消息框等,将个性化的属性数据(例如名称、标题、大小等)进行参数化,作为输入参数开放给调用者。这样用户只需要提供相应参数,即可自定义创建出需要的界面元素。
下图展示了部分当前UI_Element模块封装好的功能,可以直观地从函数名称上看出其相应的实现,如创建窗口、菜单栏、菜单、分隔符以及子菜单等:
图 4 UI_Element模块
 
// GUI模块元素的创建和布置
GUI模块中包含了对界面元素的创建、布置以及关联事件的处理函数。下面以创建按钮为例进行介绍。
-  创建按钮
创建按钮的Python语句如下:
self.IndexButton = WidgetFactory.createButton(self.fm3, '生成',self.generateIndex)
其中函数createButton所包含的三个参数为:
  • self.fm3:当前按钮的父窗口;
  • 生成:按钮的名称;
  • generateIndex:关联的事件处理函数,即点击这个按钮时执行此函数。
图 5 创建按钮函数的定义
- 按钮的布局设置
按钮创建完成后,需要考虑其布局设置,语句如下:
self.IndexButton.pack(side=LEFT, fill=NONE, padx=5, expand=YES)
函数pack是Tkinter中的布局管理器,可通过多个参数的不同配置来调整界面元素在窗口中的位置,在此简单介绍常用的四个参数:
  • side:设置该组件在父组件中的添加位置,可以设置为靠上(TOP)、靠下(BOTTOM)、靠左(LEFT)、靠右(RIGHT);
  • fill:设置该组件是否填充父组件分配的空间,可以为NONE(默认不填充)、X(水平方向填充)、Y(竖直方向填充)、BOTH(两个方向都填充,铺满);
  • padx:指定该组件在水平方向上与其他组件的间距,用数值表示;
  • expand:用YES和NO表示当父组件增大时,是否拉伸该组件;YES表示拉伸,NO表示不拉伸。
  • 关于pack的更多细节可参考Tkinter官网。
 
// GUI模块的处理函数
处理函数定义了当操作界面元素后需要执行的操作,下图是关联操作按钮的generateIndex函数的实际定义:
图 6 按钮处理函数的定义
该函数的流程图如下所示:
图 7 处理函数流程图
先判断vcm(VectorCAST项目配置管理)文件路径是否为空,如果为空则弹出消息框提示错误信息;如果不为空,则调用createIndex函数生成报告索引。生成结束后,弹出消息框显示生成的索引路径。
图 8 消息框显示保存路径
 
Part 3
小结
本文主要介绍了如何使用Python开发VectorCAST/C++ 单元测试的辅助工具,重点包括以下三点:
>
扩展Python纯脚本程序,支持界面操作,提高程序的易用性;
>
选择合适的GUI库,并开发配套的GUI模块;
>
对GUI模块进行重构以提高程序的可复用性和可扩展性。
借此机会,和大家分享我个人对软件质量的感想:从用户角度通俗地评价,高质量的软件意味着bug数量少,程序的操作稳定且执行可靠;而开发人员则会从“扩展性、复用性、维护性”这三个维度去衡量软件的质量,即整体架构设计易于扩展,模块之间耦合性低、易复用,代码简洁易懂、便于维护。伴随开发的持续重构,则是不断提升软件代码质量的利器。
 
-  作者 - 
袁梦乔     维克多汽车技术(上海)有限公司 代码测试部门

来源:Vector维克多

作者:Vector China

评论 0
同类信息