当前位置: 首页 > news >正文

信息系统开发平台OpenExpressApp:【OpenTest】 之 框架实现说明

  在信息系统开发平台OpenExpressApp:【OpenTest】 之 如何实现自动化测试框架中说了一下在OEA中使用IronRuby开发了一个自动化UI测试工具,在给测试人员使用后,他们提出一些问题,本篇将介绍一下OpenTest的内部实现的一些内容

问题

  1. 现有自动化框架的运行机制是怎样的?
  2. Utils中定义的是通用方法吗?TestObject和Utils的关系是什么?TestObject的运行是否以Utils为基础?
  3. 可以依靠哪些对象属性来定位对象?在类FindControlHelper中,是以AutomationId、Name两种属性进行定位,当AutomationId或Name相同时该如何处理?
  4. ....

框架使用方法介绍

  1. 修改inc.rb中的$ExePath = "d:/GZJ/OpenExpressApp/OpenExpressApp.Host.WPF/bin/Debug"为你的程序路径
  2. 在框架的TestCase目录下编写测试用例功能脚本文件:XXX.rb,文件大致结构如下
    view source print ?
    01$用例名称 = "这个测试用例的中文名称"  #出现错误后,邮件中会使用这个名称来报错
    02  
    03#以下两个require是必须的
    04require "inc.rb"                       
    05require "TestCase/run_app.rb"
    06  
    07#以下为用例步骤描述区域,相当于以前写的测试用例步骤
    08#用例步骤描述:
    09# 1 新增部门, 编码:Test  名称:自动化测试
    10# 2 .....
    11打开模块 "部门管理"
    12  
    13# 1 新增部门, 编码:Test  名称:自动化测试
    14添加
    15属性编辑器("编码").输入("Test")
    16属性编辑器("名称").输入("自动化测试")
    17....
  3. 在框架入口文件main.rb中增加测试用例的启动命令
    view source print ?
    01require "inc.rb"
    02require "mail.rb"
    03  
    04运行测试用例文件 "demo/project.rb"
    05运行测试用例文件 "demo/org_manage.rb"
    06#运行测试用例文件 "demo/contract.rb"
    07  
    08发送邮件
    09  
    10# TestApplication.instance.app.close
    11Playback.Cleanup()
  4. 在框架main.rb中增加邮件接收人地址
    view source print ?
    1#增加收件人列表
    2$收件人 << "zhoujg@grandsoft.com.cn"
  5. 执行rub.bat运行自动化测试脚本

运行机制

脚本运行是由run.bat启动,main.rb作为入口文件执行功能脚本文件,每个功能脚本文件最上面都有【require "TestCase/run_app.rb"】,以保证主程序已经启动。

view source print ?
1# 保证引用此单元的测试用例的先决条件是应用程序已经启动
2TestApplication.instance.run "d:/GZJ/OpenExpressApp/OpenExpressApp.Host.WPF/bin/Debug/OpenExpressApp.Host.WPF.exe", "admin", "" unless 主窗口.Exists

在功能测试脚本中,基本上都是以【打开模块】函数作为开头,打开模块内部通过模拟点击功能模块列表来打开功能模块,

view source print ?
1def 打开模块(title)
2  begin
3    m = TestApplication.instance.open_module(title)
4    设置当前测试对象 m
5    m
6  rescue
7    raise "没有打开模块 #{title}"
8  end    
9end

打开模块后会把当前打开的模块设置为默认对象,要明白这个机制就需要知道Ruby的元编程特性,【设置当前测试对象】是在object.rb中实现的。在object.rb还实现了一个重要方法【method_missing】,这可以保证后续编写的脚本作用范围都是针对当前打开模块来操作的。可以参考IronRuby:元编程特性【method_missing】的使用

view source print ?
01#测试对象链表,最后一个为当前测试对象,执行Object方法时会执行此对象的方法。加上链表主要是为了处理弹出窗口又关闭后自动切换测试对象的情况
02$CurTestObject = []
03  
04class Object
05  def 设置当前测试对象(test_object)
06    $CurTestObject << test_object
07    $CurTestObject.each { |item| puts item.FriendlyName }
08  end        
09    
10  def method_missing(name, *args, &block)    
11    if @test_control.respond_to?(name)      
12       return @test_control.send(name, *args, &block)    
13    else      
14       raise  "没有定义方法:" + name.to_s    
15    end  
16endend

打开模块后,后续脚本的基本语法参考信息系统开发平台OpenExpressApp:【OpenTest】 之 语法及其使用介绍

一个简单的语法如下:属性编辑器("编码").输入("Test")

为了理解这个脚本是如何执行以及什么意思,下面我将介绍TestObject

TestObject

TestObject是对我们设计来表示要测试的控件的一个抽象对象,我们先拿最常用的一个函数【属性编辑器】来说一下。

 

view source print ?
01def 属性编辑器(title,  type = nil)
02  begin
03    path = title.split(".")
04    obj = self
05    if path.length > 1
06      path[0..-2].each{|page_title|
07        obj = obj.页签(page_title)
08      }
09    end
10    if type == nil
11      puts "文本编辑框:" + title
12      edt = WpfEdit.new(obj.test_control)
13      edt.SearchProperties["Name"] = path[-1unless title == ""
14      obj = EditTestObject.new(edt)
15    elsif type == :下拉列表
16      puts "下拉列表编辑框:" + title
17      cb  = WpfComboBox.new(obj.test_control)
18      cb.SearchProperties["Name"] = path[-1unless title == ""
19      obj = ListComboBoxTestObject.new(cb) <BR>      ......<BRend

通过【属性编辑器】方法,我们可以获取各种不同类型(文本、下拉、枚举等)的属性编辑器,前面几行考虑了通过页签来定位控件,对于文本编辑类型代码片段如下:

 

 

view source print ?
1edt = WpfEdit.new(obj.test_control)
2edt.SearchProperties["Name"] = path[-1unless title == ""
3obj = EditTestObject.new(edt)

 

  • WpfEdit
    WpfEdit是VS2010 CodedUI中支持自动化测试框架中的类库,这个类库是针对WPF框架的UI测试对象,在使用VS2010的CodedUI来做自己的自动化测试框架中可以看到需要哪些.Net程序集,这里我们先了解,我们TestObject内部模拟UI操作来测试都是通过.Net下的测试对象来做的,所以上面提出的问题【我们依靠哪些对象属性来定位对象?】就有答案了,那就是微软提供的测试框架提供哪些属性,我们的脚本就可以用哪些属性来定位对象,只是我们现在的测试框架代码实现中考虑简单方便性而只实现了基于Name来定位的,代码如:edt.SearchProperties["Name"] = XXX (其中Name是由.Net自动化测试框架Microsoft::VisualStudio::TestTools::UITesting::WpfControls提供的),如果想根据更多条件查找,则需要写额外代码来处理。如果是共性需求,则可以修改通用方法,如果是个别控件,则需要为这个控件单独生成一个TestObject继承类,并修改传递WpfXXX测试控件的SearchProperties。
  • EditTestObject
    view source print ?
    1class EditTestObject < TestObject
    2  #动作
    3  def 输入(str)
    4    puts "输入:" + str
    5    @test_control.DrawHighlight
    6    @test_control.Text = str
    7  end
    8end
    EditTestObject是OpenTest的测试对象,它继承自TestObject,覆盖了【输入】方法。

     
  • TestObject
    view source print ?
    01class TestObject
    02  
    03  attr_accessor :test_control
    04  attr_accessor :name
    05  
    06  def initialize(test_control)
    07    @test_control = test_control
    08  end
    09  
    10  def method_missing(name, *args, &block)
    11    if @test_control.respond_to?(name)
    12      return @test_control.send(name, *args, &block)
    13    else
    14      raise  "没有定义方法:" + name.to_s
    15    end
    16  end<BR>
    TestObject是所有测试对象的基类,它的构造函数需要传入一个.Net下的测试对象(例如WpfEdit),由于实现了method_missing,所以我们可以在代码中直接写.Net下的测试对象的具体方法,如DrawHighlight。(要想明白.Net和IronRuby的交互,可以参考书籍IronRuby Unleashed
  • TestObject子类介绍
    针对不同的测试控件,我们基本上会对应从TestObject继承下来生成一个新的测试对象,如果你想支持一个新的对象,那么也应该集成TestObject生成一个新的对象。
    在编写具体查找代码时,需要注意,如果父对象是page或者TreeItem等,需要把当前的测试对象的parent置为page或者Tree、TreeItem,否则找不到。
    以下简单说明一下现在实现的一些子类:
    • CheckTestObject:勾选框
    • GridTestObject:Grid列表
    • GroupTestObject:分组对象
    • ListGridTestObject:列表Grid
    • TreeTestObject:树形控件
    • TreeItemTestObject:树节点
    • EnumTestObject:枚举下拉对象
    • ComboBoxTestObject:ComboBox控件
    • ContextMenuTestObject:弹出菜单测试对象
    • ModuleTestObject:模块
    • PageTestObject:页
    • ButtonTestObject:按钮

其他文件说明

common_func.rb:这个单元中的函数是提供给编写脚本人员使用的一些常用函数,

FindControlHelper.rb:生成测试对象的通用函数,实现方法中以AutomationId或Id来定位,如果实际查找不是这个,可以在TestObject中直接写真正的查询定位条件

mail.rb:邮件相关函数

 

推荐:你可能需要的在线电子书

 

欢迎转载,转载请注明:转载自周金根 [ http://zhoujg.cnblogs.com/ ]

相关文章:

  • 优秀者是真的优秀
  • PKU 1011
  • 阿里巴巴加强个人信息保护 获中央网信办等四部委点赞
  • mfc框架下osg的内存泄露问题(转)
  • SQL优化系列:别让强制类型转换偷走性能
  • 基于TCP的通信程序设计
  • 阿里云前端周刊 - 第 26 期
  • 您小程序了吗? 专家一语道破小程序安全本质
  • MySQL的 insert into ... on duplicate key update语句
  • 设计图片绘制的展现
  • Vue全家桶实现一个Web App
  • 1.基础知识
  • 请教oschina缓存设计和效率问题(某些表查询后即需要更新某字段的情况如何缓存)...
  • IBM开源JVM实现OpenJ9,并提交Eclipse基金会托管
  • Exchange2007 Web/Outlook邮箱界面语言设定
  • [iOS]Core Data浅析一 -- 启用Core Data
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • 10个确保微服务与容器安全的最佳实践
  • 3.7、@ResponseBody 和 @RestController
  • el-input获取焦点 input输入框为空时高亮 el-input值非法时
  • Hibernate最全面试题
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • JAVA SE 6 GC调优笔记
  • k8s如何管理Pod
  • laravel with 查询列表限制条数
  • Linux链接文件
  • Linux中的硬链接与软链接
  • Mac转Windows的拯救指南
  • Python_网络编程
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • sessionStorage和localStorage
  • tweak 支持第三方库
  • 反思总结然后整装待发
  • 搞机器学习要哪些技能
  • 机器学习 vs. 深度学习
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 力扣(LeetCode)357
  • 前端之Sass/Scss实战笔记
  • 系统认识JavaScript正则表达式
  • 走向全栈之MongoDB的使用
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • ​configparser --- 配置文件解析器​
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • ​七周四次课(5月9日)iptables filter表案例、iptables nat表应用
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • $(selector).each()和$.each()的区别
  • (3)选择元素——(17)练习(Exercises)
  • (附源码)springboot助农电商系统 毕业设计 081919
  • (附源码)ssm航空客运订票系统 毕业设计 141612
  • (转)用.Net的File控件上传文件的解决方案