QTP – 快速指南
QTP – 快速指南
QTP – 简介
QTP代表Q uick Ť EST P rofessional,的产物ħ ewlett P ackard (HP) 。该工具可帮助测试人员在脚本开发完成后无缝执行自动化功能测试,无需监控。
HP QTP 使用Visual Basic Scripting (VBScript)来自动化应用程序。脚本引擎不需要单独安装,因为它是 Windows 操作系统的一部分。VBScript 的当前版本是 5.8,它作为 Win 7 的一部分提供。VBScript 不是面向对象的语言,而是基于对象的语言。
测试工具
软件测试环境中的工具可以定义为支持一个或多个测试活动的产品,包括计划、需求、创建构建、测试执行、缺陷记录和测试分析。
工具分类
工具可以根据几个参数进行分类。它包括 –
- 工具的目的
- 工具内支持的活动
- 它支持的测试类型/级别。
- 许可类型(开源、免费、商业)
- 使用的技术
工具类型
Sr.No. | 刀具类型 | 用于 | 使用人 |
---|---|---|---|
1 | 测试管理工具 | 测试管理、调度、缺陷记录、跟踪和分析。 | 测试员 |
2 | 配置管理工具 | 用于实施、执行、跟踪变更 | 所有团队成员 |
3 | 静态分析工具 | 静态测试 | 开发商 |
4 | 测试数据准备工具 | 分析设计、测试数据生成 | 测试员 |
5 | 测试执行工具 | 实施、执行 | 测试员 |
6 | 测试比较器 | 比较预期和实际结果 | 所有团队成员 |
7 | 覆盖率测量工具 | 提供结构覆盖 | 开发商 |
8 | 性能测试工具 | 监控性能、响应时间 | 测试员 |
9 | 项目规划和跟踪工具 | 计划 | 项目经理 |
10 | 事件管理工具 | 用于管理测试 | 测试员 |
QTP 适用于何处?
QTP 是一种功能测试工具,最适合应用程序的回归测试。QTP 是 HP 拥有的许可/商业工具,是市场上最受欢迎的工具之一。它比较实际结果和预期结果,并在执行摘要中报告结果。
QTP – 历史与演变
HP Quick Test Professional 最初由 Mercury Interactive 所有,后来被 HP 收购。它的原名是 Astra Quick Test,后来被命名为 Quick Test Professional,但最新版本被称为 Unified Functional Tester (UFT)。
版本历史
现在让我们来看看 QTP 的版本历史。
Versions | 时间线 |
---|---|
Astra Quick Test v1.0 to v5.5 – Mercury Interactive | 1998年5月至2001年8月 |
QuickTest Professional v6.5 to v9.0 – Mercury Interactive | 2003年9月至2006年4月 |
Hp-QuickTest Professional v9.1 to v11.0 – Acquired and Released by HP | 2007年2月至2010年9月 |
Hp-Unified Functional Testing v11.5 to v11.53 | 2012年至2013年11月 |
优点
-
使用 VBScript 开发自动化测试不需要高度熟练的编码人员,并且与其他面向对象的编程语言相比相对容易。
-
易于使用、易于导航、结果验证和报告生成。
-
与测试管理工具 (Hp-Quality Center) 轻松集成,可轻松安排和监控。
-
也可用于移动应用程序测试。
-
由于它是 HP 产品,HP 及其论坛为解决技术问题提供全面支持。
缺点
-
与 Selenium 不同,QTP 仅适用于 Windows 操作系统。
-
并非所有版本的浏览器都受支持,测试人员需要等待每个主要版本的补丁发布。
-
话虽如此,它是一个商业工具,许可成本非常高。
-
尽管脚本时间较短,但执行时间相对较长,因为它会给 CPU 和 RAM 带来负载。
QTP – 自动化测试流程
对于任何自动化工具实施,以下是它的阶段/阶段。每个阶段都对应一个特定的活动,每个阶段都有一个明确的结果。
-
测试自动化可行性分析– 第一步是检查应用程序是否可以自动化。由于其局限性,并非所有应用程序都可以自动化。
-
适当的工具选择– 下一个最重要的步骤是选择工具。这取决于构建应用程序的技术、其功能和用途。
-
评估合适的框架– 选择工具后,下一个活动是选择合适的框架。框架有很多种,每个框架都有自己的意义。我们将在本教程后面详细介绍框架。
-
构建概念证明 – 概念证明 (POC) 是使用端到端场景开发的,以评估该工具是否可以支持应用程序的自动化。它是通过端到端场景执行的,可确保主要功能可以自动化。
-
开发自动化框架– 在构建 POC 后,进行框架开发,这是任何测试自动化项目成功的关键步骤。框架应该在仔细分析应用程序使用的技术及其关键特性之后构建。
-
开发测试脚本、执行和分析– 脚本开发完成后,将执行脚本,分析结果并记录缺陷(如果有)。测试脚本通常是版本控制的。
QTP – 环境设置
QTP 是一个商业工具,试用版可以直接从 HP 网站下载。只有当前版本,即统一功能测试 (11.5x) 可供下载。以下是可以下载试用版的 URL。
下载 URL – QTP
安装程序
步骤 1 – 单击“试用和演示”链接并选择“HP Unified Functional Testing 11.50 CC English SW E-Media Evaluation”,如下所示 –
步骤 2 – 选择“HP Unified Functional Testing 11.50”后,下载向导将打开。填写个人详细信息,然后单击下一步。
第 3 步– 阅读“使用条款”并单击“下一步”。
步骤 4 – 下载窗口打开。现在,单击“下载”按钮。
步骤 5 – 下载的文件格式为 .RAR。现在您需要解压缩存档,文件夹内容如下所示并执行 Setup.exe。
步骤 6 – 执行安装文件后,为了安装,从列表中选择“统一功能测试设置”,如下所示 –
步骤 7 – 然后单击下一步继续。
步骤 8 – 在自定义设置窗口中,选择自动化所需的插件,即您应该根据被测应用程序的技术选择插件。例如,如果您的应用程序基于 .NET,那么您应该确保选择 .NET。
步骤 9 – 选择安装所需的插件后,单击下一步。安装完成后,您将看到一个完成按钮的窗口。
步骤 10 – 完成安装后,“其他安装要求”对话框将打开。选择列表中除“运行许可证安装向导”之外的所有内容,然后单击“运行”。我们不需要选择“运行许可证安装向导”,因为我们正在安装试用版,默认情况下,它提供 30 天的许可证。
步骤 11 – 完成附加安装要求后,会显示一个勾号,这反过来表明组件已成功安装。现在,单击关闭。
启动 UFT 和插件页面
步骤 1 – 安装后,可以从开始菜单启动应用程序,如图所示。
步骤 2 – 出现许可证页面。您可以单击继续,因为我们已经安装了试用许可证。
步骤 3 – 加载项对话框打开,供用户选择所需的加载项。
注意– 不要加载所有加载项,而只是加载所需的加载项,然后单击确定。
步骤 4 – 加载所需的插件后,UFT 11.5 工具为用户打开,第一眼看到 UFT 外观,如下所示 –
QTP – 记录和回放
记录测试对应于记录被测应用程序的用户操作,以便 UFT 自动生成可回放的脚本。如果初始设置正确,Record and Playback 可以给我们该工具的第一印象,它是否支持该技术。
录制和播放步骤如下 –
步骤 1 – 从起始页单击“新建”测试,如下所示 –
第 2 步– 单击“新建”链接,将打开一个新的测试窗口,用户需要选择测试类型。选择“GUI 测试”,为测试命名以及需要保存的位置。
步骤 3 – 创建新测试后,新测试屏幕将打开,如下所示。现在,单击“Action1”选项卡,该选项卡默认使用 1 个操作创建。
步骤 4 – 单击“录制”菜单并选择“录制和运行设置”,如下所示 –
第 5 步– 记录和运行设置对话框打开,根据应用程序类型,可以选择 Web、Java 或 Windows 应用程序。例如,在这里,我们将记录一个基于 Web 的应用程序 (http://easycalculation.com/)。
步骤 6 – 单击记录。Internet Explorer根据设置自动打开,网址为https://www.easycalculation.com/。单击“代数”下的“数字”链接并输入一个数字并点击“计算”。完成动作后,单击录制面板中的“停止”按钮。您会注意到脚本的生成如下所示 –
步骤 7 – 现在通过单击播放按钮播放脚本。脚本重放并显示结果。
Step 8 – 默认情况下打开结果窗口,其中准确显示执行、通过和失败步骤的时间戳。
录音回放的意义
-
它用作初步调查方法,以验证 UFT 是否可以支持该技术/应用程序。
-
用于创建测试应用程序的基本功能或不需要长期维护的特性。
-
它可用于记录鼠标移动和键盘输入。
录制模式
-
正常记录– 这是默认记录模式,记录对象和在被测应用程序上执行的操作。
-
模拟记录– 这不仅记录键盘操作,还记录鼠标相对于屏幕或应用程序窗口的移动。
-
低级记录– 这会记录对象的确切坐标,而与 UFT 是否识别对象无关。它只记录坐标,因此不记录鼠标移动。
-
Insight Recording – UFT 根据其外观而不是根据其本机属性记录操作。
如何选择录制模式
单击“录制”按钮后,一旦录制开始,用户就可以从出现在屏幕上的录制窗格中选择录制模式。可以从上面讨论过的任何一个中进行选择。
您会看到以下场景在所有模式下都被记录,并且在各种情况下都记录了相同的动作。
- 启动 IE – https://www.easycalculation.com/
- 点击“代数”下的“数字”
- 点击“平方根”链接
- 输入一个值来计算平方根。让我们说 10
- 点击计算
在默认,模拟和低电平记录模式下记录的脚本如下 –
' DEFAULT RECORDING MODE Browser("Free Online Math Calculator").Page("Free Online Math Calculator").Link("Numbers").Click Browser("Free Online Math Calculator").Page("Numbers Calculator - Math").Link("Square Root").Click Browser("Free Online Math Calculator").Page("Square Root Calculator").WebEdit("n").Set "10" Browser("Free Online Math Calculator").Page("Square Root Calculator").WebButton("calculate").Click ' ANALOG RECORDING MODE Desktop.RunAnalog "Track1" ' LOW LEVEL RECORDING MODE Window("Windows Internet Explorer").WinObject("Internet Explorer_Server").Click 235,395 Window("Windows Internet Explorer").WinObject("Internet Explorer_Server").Click 509,391 Window("Windows Internet Explorer").WinObject("Internet Explorer_Server").Click 780,631 Window("Windows Internet Explorer").WinObject("Internet Explorer_Server").Type "10" Window("Windows Internet Explorer").WinObject("Internet Explorer_Server").Click 757,666
使用洞察记录模式的记录如下所示 –
QTP – 对象存储库
对象库
Object Repository 是对象和属性的集合,QTP 可以使用它来识别对象并对其进行操作。当用户记录测试时,默认情况下会捕获对象及其属性。如果不了解对象及其属性,QTP 将无法播放脚本。
单击以下每个主题以了解有关 Object Repository 及其相关功能的更多信息。
Sr.No. | 主题和描述 |
---|---|
1 | Object Spy and its Features
了解对象间谍的用法及其相关功能。 |
2 | Working with Object Repository
从对象存储库中添加、编辑、删除对象及其相关功能。 |
3 | Types of Object Repository
处理共享对象和本地对象存储库及其与脚本相关的上下文。 |
4 | User-defined Objects
处理使用用户定义对象的情况。 |
5 | Object Repository in XML
处理将 OR 转换为 XML 并将对象存储库用作 XML。 |
6 | Comparing and Merging OR
诸如比较 OR’、合并 OR 之类的操作以有效地与对象存储库一起工作。 |
7 | Ordinal Identifiers
使用序数标识符的情况及其优点。 |
8 | Child Objects
使用子对象进行有效的脚本编写 |
QTP – 动作
Actions 帮助测试人员将脚本划分为 QTP 语句组。动作类似于 VBScript 中的函数;但是,也有一些不同之处。默认情况下,QTP 使用一个操作创建一个测试。
Actions | 功能 |
---|---|
Action is an in-built feature of QTP. | VBScript 和 QTP 都支持 VBScript 函数。 |
Actions parameters are passed by value only. | 函数参数通过值或引用传递。 |
Actions have extension .mts | 函数保存为 .vbs 或 .qfl |
Actions may or may not be reusable. | 函数总是可重用的。 |
可以通过右键单击脚本编辑器窗口并选择“属性”来访问动作的属性。
操作属性包含以下信息 –
- 动作名称
- 地点
- 可重复使用的标志
- 输入参数
- 输出参数
动作类型
有三种类型的操作 –
-
不可重用动作– 只能在设计的特定测试中调用的动作,并且只能调用一次。
-
Reusable action – 可以多次调用的动作,它所在的任何测试,也可以被任何其他测试使用。
-
外部可重用操作– 它是存储在另一个测试中的可重用操作。外部操作在调用测试中是只读的,但可以在本地使用外部操作的数据表信息的可编辑副本。
使用动作
有三个选项可以插入一个动作。单击其中的每一个以了解有关所选操作类型的更多信息。
Sr.No. | 动作类型和描述 |
---|---|
1 | Insert Call to New Action
从现有动作插入新动作 |
2 | Insert Call to Copy of Action
插入现有操作的副本 |
3 | Insert Call to Existing Action
插入对现有可重用操作的调用 |
QTP – 数据表
DataTable 类似于 Microsoft Excel,可帮助测试人员创建可用于多次运行 Action 的数据驱动测试用例。有两种类型的数据表 –
-
本地数据表– 每个操作都有自己的私有数据表,也称为本地数据表,也可以跨操作访问。
-
全局数据表– 每个测试都有一个全局数据表,可跨操作访问。
可以从 QTP 的“数据”选项卡访问数据表,如下所示 –
要执行某个指定迭代次数的测试用例,可以在“测试设置”对话框中设置全局数据表的迭代,可以使用文件 → 设置 → 运行 (Tab) 访问,如下所示 –
例子
例如,如果用户想要参数化可以使用http://easycalculation.com/compound-interest.php访问的http://easycalculation.com/ 的“复合兴趣” 。可以按如下所示创建参数。Excel 的大部分功能也可以在数据表中使用。
数据表操作
有三种类型的对象可以访问 DataTable。通过遍历以下内容可以很好地理解数据表操作 –
Sr.No. | 对象类型和描述 |
---|---|
1 | Data Table Methods
提供有关数据表方法的详细信息。 |
2 | DTParameter Object Methods
提供有关 DTParameter 方法的详细信息。 |
3 | DTSheet Object Methods
提供有关 DTSheet 方法的详细信息。 |
QTP – 检查点
顾名思义,检查点是指将指定属性的当前值或对象的当前状态与预期值进行比较的验证点,可以在脚本中的任何时间点插入该值。
检查点的类型
Sr.No. | 类型和描述 |
---|---|
1 |
Standard Checkpoint 验证受测应用程序中对象的属性值,并受所有加载项环境支持。 |
2 |
Bitmap Checkpoint 将应用程序的某个区域验证为位图 |
3 |
File Content Checkpoint 验证动态生成或访问的文件(如 .txt、.pdf)中的文本 |
4 |
Table Checkpoint 验证表中的信息。并非所有环境都受支持。 |
5 |
Text Checkpoint 根据指定的条件,验证是否在基于 Windows 的应用程序的定义区域内显示的文本。 |
6 |
Text Area Checkpoint 根据指定的标准,验证文本字符串是否显示在基于 Windows 的应用程序的定义区域内。 |
7 |
Accessibility Checkpoint 验证页面并报告可能不符合万维网联盟 (W3C) Web 内容可访问性指南的网站区域 |
8 |
Page Checkpoint 验证网页的特征。它还可以检查断开的链接。 |
9 |
Database Checkpoint 验证被测应用程序访问的数据库内容。 |
10 |
XML Checkpoint 验证 .xml 文档或 Web 页面和框架中的 .xml 文档的内容。 |
插入检查点
当用户想要插入检查点时,必须确保仅在录制会话期间支持大多数检查点。一旦用户停止录制,就不会启用检查点。
下面给出的是检查点菜单,当用户未处于录制模式时。
下面给出了检查点菜单,当用户处于录制模式时。
例子
为被测应用程序添加检查点 – “http://easycalculation.com/”
' 1. Inserted Standard Checkpoint Status = Browser("Math Calculator").Page("Math Calculator").Link("Numbers").Check CheckPoint("Numbers") If Status Then print "Checkpoint Passed" Else Print "Checkpoint Failed" End if ' 2. Inserted BitMap Checkpoint imgchkpoint = Browser("Math Calculator").Page("Math Calculator").Image("French").Check CheckPoint("French") If imgchkpoint Then print "Checkpoint Passed" Else Print "Checkpoint Failed" End if
查看检查点属性
插入后,如果测试人员想要更改值,我们可以通过右键单击脚本的关键字“检查点”并导航到“检查点属性”来实现,如下所示 –
您也可以在对象存储库中找到相同的检查点,如下所示。它准确地显示了使用的检查点类型以及预期值和超时值。
QTP – 同步
同步点是工具和被测应用程序之间的时间接口。同步点是一个特性,用于指定测试脚本的两个步骤之间的延迟时间。
例如,点击一个链接加载页面可能需要 1 秒,有时需要 5 秒,甚至可能需要 10 秒才能完全加载。它取决于各种因素,例如应用程序服务器响应时间、网络带宽和客户端系统功能。
如果时间变化,则脚本将失败,除非测试人员智能地处理这些时间差异。
插入同步点的方法
- 等待属性
- 存在
- 等待
- 同步(仅适用于基于 Web 的应用程序)
- 插入 QTP 内置同步点。
让我们说,我们需要在点击“数字”链接和点击“ www.easycalculation.com ”中的“简单兴趣”计算器之间插入一个同步点。我们现在将看看为上述场景插入同步点的所有五种方法。
方法 1 – WaitProperty
WaitProperty 是一种以属性名称、值和超时值作为输入来执行同步的方法。这是一个动态等待,因此鼓励使用此选项。
' Method 1 - WaitProperty with 25 seconds Dim obj Set obj = Browser("Math Calculator").Page("Math Calculator") obj.Link("Numbers").Click obj.Link("Simple Interest").WaitProperty "text", "Simple Interest",25000 obj.Link("Simple Interest").Click
方法 2 – 存在
Exist 是一种将 Timeout 值作为输入来执行同步的方法。同样,这是一个动态等待,因此鼓励使用此选项。
' Method 2 : Exist Timeout - 30 Seconds Dim obj Set obj = Browser("Math Calculator").Page("Math Calculator") obj.Link("Numbers").Click If obj.Link("Simple Interest").Exist(30) Then obj.Link("Simple Interest").Click Else Print "Link NOT Available" End IF
方法 3 – 等待
等待是一个硬编码的同步点,它等待独立于事件发生与否。因此,不鼓励使用 Wait,它可以用于较短的等待时间,例如 1 或 2 秒。
' Method 3 : Wait Timeout - 30 Seconds Dim obj Set obj = Browser("Math Calculator").Page("Math Calculator") obj.Link("Numbers").Click wait(30) Browser("Math Calculator").Page("Math Calculator").Link("Simple Interest").Click
方法 4 – 同步方法
同步方法只能用于页面加载之间始终存在延迟的 Web 应用程序。
' Method 4 : Dim obj Set obj = Browser("Math Calculator").Page("Math Calculator") obj.Link("Numbers").Click Browser("Math Calculator").Sync Browser("Math Calculator").Page("Math Calculator").Link("Simple Interest").Click
方法 5 – 插入 QTP 内置同步点
步骤 1 – 进入录制模式。如果用户未处于录制模式,则此选项将被禁用。
第 2 步– 转到“设计”→“同步点”。
第 3 步– 我们需要选择我们想要成为同步点的对象。选择对象后,对象窗口打开,如下所示 –
步骤 4 – 单击确定;“添加同步窗口”打开。选择属性、值和超时值,然后单击确定,如下所示 –
第 5 步– 将生成如下所示的脚本,这与我们已经讨论过的 WaitProperty(方法 1)相同 –
Browser("Math Calculator").Page("Math Calculator").Link("Numbers").Click Browser("Math Calculator").Page("Math Calculator").Link("Simple Interest").WaitProperty "text", "Simple Interest", 10000
默认同步
当用户没有使用上述任何一种同步方法时,QTP 仍然有一个内置的对象同步超时,可以由用户调整。
导航到“文件”>>“设置”>>运行选项卡>>对象同步超时,如下所示。
QTP – 智能识别
有时,QTP 无法找到任何与识别对象描述匹配的对象,或者它可能会找到多个符合描述的对象,然后 QTP 会忽略已识别的描述并使用智能识别机制来识别对象。
QTP 的智能识别使用两种类型的属性 –
-
基本过滤器属性– 特定测试对象类的基本属性,其值不能在不改变原始对象本质的情况下更改。
-
可选过滤器属性– 其他属性也有助于识别特定类的对象,其属性不太可能经常更改,但如果它们不再适用,则可以忽略。
为对象启用智能识别
步骤 1 – 导航到“工具”→“对象识别”。对象识别对话框打开。
步骤 2 – 选择环境、对象类别并打开“启用智能识别”,如下所示 –
步骤 3 – 单击配置并选择基本和可选过滤器属性。
步骤 4 – 除了默认属性之外,在基本属性中添加属性,并添加/删除可选过滤器属性。请注意,相同的属性不能同时属于强制属性和辅助属性,然后单击“确定”。
步骤 5 – 在对象存储库中添加该类型的对象后,验证是否启用了智能识别。智能识别设置为 TRUE。如果我们不想启用智能识别,我们也可以将其设为 False。
步骤 6 – 我们甚至可以通过在“文件”菜单的“设置”下的测试脚本级别应用来禁用测试级别,如下所示 –
第 7 步– 如果按照第 6 步禁用智能识别,则它不会在脚本执行期间对任何对象应用智能识别。
第 8 步– 如果将对象添加为关闭智能识别,QTP 将来不会使用智能识别进行识别,即使我们稍后启用了它。
QTP – 调试
在自动化测试上下文中,调试是一个系统的过程,用于发现和修复自动化脚本中的编码问题,从而使脚本更加健壮并能够发现应用程序中的缺陷。
在 QTP 中有多种使用断点执行调试的方法。只需按“F9”或使用菜单选项“运行”→“插入/删除断点”即可插入断点。
插入断点后,“红色”点和线将以红色突出显示,如下所示 –
Method | 捷径 | 描述 |
---|---|---|
Step Into | F11 | 用于执行每一个步骤。进入函数/动作并逐行执行。它在执行后在每一行暂停。 |
Step Over | F10 | 用于跳过函数。Step Over 仅运行活动文档中的当前步骤。 |
Step Out | Shift+F11 | 步入函数后,您可以使用步出命令。Step Out 继续运行到函数结束,然后在下一行暂停运行会话。 |
断点中的选项
可以通过“运行”菜单导航来访问断点中的各种选项。
Sr.No. | 快捷方式和说明 |
---|---|
1 |
F9 插入/删除断点 |
2 |
Ctrl+F9 启用/禁用断点 |
3 |
Ctrl+Shift+F9 清除所有断点 |
4 |
Use Only Menu 启用/禁用所有断点 |
调试面板
以下是调试窗口中的窗格 –
-
输出– 此选项卡显示打印语句的所有输出。
-
Watch – 此选项卡显示给定表达式的布尔输出。
-
LocalVariables – 此选项卡显示本地变量的输出。
例子
观察窗格显示输出表达式,如下所示 –
局部变量窗格显示局部变量保存的值,如下所示 –
QTP – 错误处理
QTP 中有多种处理错误的方法。有三种可能的错误类型,一种是在使用 QTP 时会遇到的。他们是 –
- 语法错误
- 逻辑错误
- 运行时错误
错误类型
语法错误
语法错误是拼写错误或不符合 VBscripting 语言语法的一段代码。语法错误发生在代码编译时,并且在错误被修复之前无法执行。
要验证语法,请使用键盘快捷键 Ctrl+F7,结果如下所示。如果未显示该窗口,则可以导航到“查看”→“错误”。
逻辑错误
如果脚本在语法上是正确的但它产生了意外的结果,那么它被称为逻辑错误。逻辑错误通常不会中断执行,但会产生不正确的结果。由于各种原因,即错误的假设或对需求的误解以及有时不正确的程序逻辑(使用 do-while 而不是 do-Until)或无限循环,可能会发生逻辑错误。
检测逻辑错误的方法之一是执行同行评审并验证 QTP 输出文件/结果文件,以确保该工具按预期方式执行。
运行时错误
顾名思义,这种错误发生在运行时。出现此类错误的原因是尝试执行某事的脚本无法执行,并且脚本通常会停止,因为它无法继续执行。运行时错误的经典示例是 –
- 未找到文件,但脚本试图读取文件
- 未找到对象,但脚本正在尝试对该特定对象执行操作
- 一个数除以零
- 访问数组元素时数组索引越界
处理运行时错误
有多种方法可以处理代码中的错误。
1. 使用测试设置– 错误处理可以通过导航到“文件”>>“设置”>>“运行”选项卡来定义测试设置,如下所示。我们可以选择任何指定的设置,然后单击“确定”。
2. 使用 On Error 语句– “On Error”语句用于通知 VBScript 引擎处理测试人员运行时错误的意图,而不是允许 VBScript 引擎显示对用户不友好的错误消息。
-
On Error Resume Next – On Error Resume Next 通知 VBScript 引擎在遇到错误时处理执行下一行代码。
-
On error Goto 0 – 这有助于测试人员关闭错误处理。
3. 使用 Err 对象– 错误对象是 VBScript 中的一个内置对象,它捕获运行时错误编号和错误描述,我们可以使用它们轻松调试代码。
-
Err.Number – Number 属性返回或设置指定错误的数值。如果 Err.Number 值为 0,则未发生错误。
-
Err.Description – Description 属性返回或设置有关错误的简短描述。
-
Err.Clear – Clear 方法重置 Err 对象并清除与其关联的所有先前值。
例子
'Call the function to Add two Numbers Call Addition(num1,num2) Function Addition(a,b) On error resume next If NOT IsNumeric(a) or IsNumeric(b) Then Print "Error number is " & err.number & " and description is : " & err.description Err.Clear Exit Function End If Addition = a+b 'disables error handling On Error Goto 0 End function
4. 使用退出语句– 退出语句可以与 Err 对象一起使用,以根据 Err.Number 值退出测试、操作或迭代。让我们详细看看这些 Exit 语句中的每一个。
-
ExitTest – 从整个 QTP 测试中退出,无论运行时迭代设置是什么。
-
ExitAction – 退出当前操作。
-
ExitActionIteration – 退出操作的当前迭代。
-
ExitTestIteration – 退出 QTP 测试的当前迭代并进行下一次迭代。
5. 恢复场景– 遇到错误时,将根据特定条件触发恢复场景,并在单独的章节中详细介绍。
6. Reporter Object – Reporter Object 帮助我们向运行结果报告事件。它帮助我们确定相关操作/步骤是否通过/失败。
'Syntax: Reporter.ReportEventEventStatus, ReportStepName, Details, [ImageFilePath] 'Example Reporter.ReportEvent micFail, "Login", "User is unable to Login."
QTP – 恢复方案
恢复方案
在执行 QTP 脚本时,我们可能会遇到一些意外错误。为了从这些意外错误中恢复测试并继续执行脚本的其余部分,使用了恢复方案。可以通过导航到“资源”→ 恢复方案管理器来访问恢复方案管理器,如下所示 –
创建恢复场景的步骤
步骤 1 – 单击“新建”恢复方案按钮;恢复场景向导将打开,如下所示 –
步骤 2 – 选择触发事件。它对应于事件,可以在以下四个事件中的任何一个中出现 –
- 弹出窗口
- 对象状态
- 试运行错误
- 应用程序崩溃
步骤 3 – 恢复操作窗口打开。恢复操作可以执行以下任何操作,如下面的屏幕截图所示 –
步骤 4 – 指定适当的恢复操作后,我们还需要指定后恢复操作,如下所示 –
步骤 5 – 指定恢复后操作后,应命名恢复场景并将其添加到测试中,以便可以激活它。
步骤 6 – 恢复场景创建完成,需要通过选中“将场景添加到当前测试”选项并单击“完成”来映射到当前测试。
步骤 7 – 添加的恢复场景如下所示,然后单击“关闭”按钮继续。
步骤 8 – 单击关闭按钮后,QTP 会提示用户保存创建的恢复方案。它将以扩展名 .qrs 保存,向导将关闭。
确认
创建的恢复场景现在应该是测试的一部分,可以通过导航到“文件”→“设置”→“恢复”选项卡来验证。
QTP – 环境变量
QTP 环境变量是特殊类型的变量,所有动作、函数库和恢复场景都可以访问。Windows 的内置环境变量可用于该特定系统上运行的所有应用程序,但 QTP 环境变量仅在运行时可用于该特定测试脚本。
环境变量的类型
内置环境变量– 提供一系列环境参数,可以提供测试名称、操作名称、测试路径、本地主机名、操作系统名称、类型及其版本等信息。可以通过导航到“文件”→“测试设置”→“环境”选项卡来访问环境变量名称。
用户定义的内部– 可以通过在环境选项卡窗口中选择“用户定义”来保存用户定义的变量。单击“&plus”按钮以输入参数名称和值,如下所示 –
用户定义的外部– 用户定义的变量可以作为 .xml 文件存储在外部文件中,并且可以加载到测试中,如下图所示。它也可以在运行时动态加载,如下面的示例之一所述。
环境变量 – 支持的方法
1. ExternalFileName 属性– 返回在“测试设置”对话框的“环境”选项卡中指定的已加载外部环境变量文件的名称。如果没有加载外部环境变量文件,则此属性返回一个空字符串。
x = Environment.ExternalFileName print x
2. LoadFromFile 方法– 在运行时动态加载指定的环境变量文件 (.xml)。使用此方法时,环境变量不需要手动添加到环境选项卡中。
Environment.LoadFromFile "D:\config.xml" b = Environment.Value("Browser") print b
3. Value Property – 检索环境变量的值。我们还可以使用此属性设置用户定义的内部环境变量的值。
' Get the Value of the InBuilt Environment Variables a = Environment.Value("OS") print a b = Environment.Value("ActionName") print b 'Loaded from External File Environment.LoadFromFile "D:\config.xml" c = Environment.Value("Browser") print c
QTP – 库文件
为了模块化脚本,库文件被添加到 QTP 脚本中。它包含变量声明、函数、类等。它们支持可跨测试脚本共享的可重用性。它们以扩展名 .vbs 或 .qfl 保存
可以通过导航到“文件”>>“函数库”来创建新的库文件。
关联函数库
方法 1 – 通过使用“文件”>“设置”>资源>关联函数库选项。单击“&plus”按钮添加函数库文件并使用实际路径或相对路径添加它,如下所示 –
方法 2 – 使用 ExecuteFile 方法。
'Syntax : ExecuteFile(Filepath) ExecuteFile "C:\lib1.vbs" ExecuteFile "C:\lib2.vbs"
方法 3 – 使用 LoadFunctionLibrary 方法。
'Syntax : LoadFunctionLibrary(Filepath) LoadFunctionLibrary "C:\lib1.vbs" LoadFunctionLibrary "C:\lib2.vbs"
方法 4 – 自动化对象模型(AOM) – 这是一种机制,使用它,我们可以控制 QTP 之外的各种 QTP 操作。使用AOM,我们可以启动QTP,打开测试,关联函数库等。下面的VbScript 应该以扩展名.vbs 保存,执行后,QTP 将启动,测试将开始执行。AOM 将在后面的章节中详细讨论。
'Launch QTP Set objQTP = CreateObject("QuickTest.Application") objQTP.Launch objQTP.Visible = True 'Open the test objQTP.Open "D:\GUITest2", False, False Set objLib = objQTP.Test.Settings.Resources.Libraries 'Associate Function Library if NOT associated already. If objLib.Find("C:\lib1.vbs") = -1 Then objLib.Add "C:\lib1.vbs", 1 End
QTP – 自动测试结果
检测结果
测试结果窗口为我们提供了足够的信息来显示通过的步骤、失败的步骤等。测试执行后结果窗口会自动打开(按照默认设置)。显示以下信息 –
- 通过的步骤
- 步骤失败
- 环境参数
- 图形统计
在测试结果中执行的操作
将结果转换为 HTML
在结果查看器窗口中,导航到“文件”→“导出到文件”。导出运行结果对话框打开,如下所示 –
我们可以选择要导出的报告类型。它可以是简短的结果,也可以是详细的结果,甚至我们可以选择节点。选择文件名并导出后,文件将保存为 .HTML 文件
过滤结果
结果可以根据状态、节点类型和迭代进行过滤。可以使用“测试结果窗口”中的过滤器按钮访问它。
提高缺陷
通过访问“工具”→“添加缺陷”,可以直接从测试结果窗口窗格将缺陷记录到 QC 中,这会打开与 ALM 的连接,如下所示 –
检测结果
可以在“工具”→“选项”→“运行会话”选项卡下配置自动测试结果窗口。如果需要,我们可以将其关闭,也可以打开“会话结束时自动导出结果”。
可以根据设置记录屏幕截图或电影。同样可以在“工具”→“选项”→“屏幕捕获”选项卡下进行配置。我们可以根据以下三个条件保存屏幕截图或电影 –
- 对于错误
- 总是
- 对于错误和警告
QTP – 使用 GUI 对象
在脚本执行过程中,有各种 GUI 对象,QTP 会与之交互。因此,了解关键 GUI 对象的基本方法很重要,我们将能够使用这些方法有效地处理它。
使用文本框
以下是我们在运行时访问文本框的方法 –
-
Set – 帮助测试人员将值设置到文本框中
-
单击–单击文本框
-
SetSecure – 用于安全地设置密码框中的文本
-
WaitProperty – 等待直到属性值变为真
-
存在– 检查文本框的存在
-
GetROProperty(“text”) – 获取文本框的值
-
GetROProperty(“Visible”) – 如果可见则返回布尔值
例子
Browser("Math Calculator").Sync Set Obj = Browser("Math Calculator").Page("SQR Calc").WebEdit("n") 'Clicks on the Text Box Obj.Click 'Verify if the Object Exist - Returns Boolean value a = obj.Exist print a 'Set the value obj.Set "10000" : wait(2) 'Get the Runtime Object Property - Value of the Text Box val = obj.GetROProperty("value") print val 'Get the Run Time Object Property - Visiblility - Returns Boolean Value x = Obj.GetROProperty("visible") print x
使用复选框
以下是一些可以使用复选框的关键方法 –
-
Set – 帮助测试人员设置复选框值“ON”或“OFF”
-
单击–单击复选框。甚至检查 ON 或 OFF 但用户不会确定状态
-
WaitProperty – 等待直到属性值变为真
-
存在– 检查复选框是否存在
-
GetROProperty(“name”) – 获取复选框的名称
-
GetROProperty(“Visible”) – 如果可见则返回布尔值
例子
'To Check the Check Box Set Obj = Browser("Calculator").Page("Gmail").WebCheckBox("PersistentCookie") Obj.Set "ON" 'To UnCheck the Check Box Obj.Set "OFF" 'Verifies the Existance of the Check box and returns Boolean Value val = Obj.Exist print val 'Fetches the Name of the CheckBox a = Obj.GetROProperty("name") print a 'Verifies the visible property and returns the boolean value. x = Obj.GetROProperty("visible") print x
使用单选按钮
以下是一些可以使用 Radio Button 的关键方法 –
-
Select(RadioButtonName) – 帮助测试人员将单选框设置为“ON”
-
单击–单击单选按钮。即使单选按钮打开或关闭,但测试人员无法获得状态
-
WaitProperty – 等待直到属性值变为真
-
存在– 检查单选按钮是否存在
-
GetROProperty(“name”) – 获取单选按钮的名称
-
GetROProperty(“Visible”) – 如果可见则返回布尔值
例子
'Select the Radio Button by name "YES" Set Obj = Browser("Calculator").Page("Forms").WebRadioGroup("group1") Obj.Select("Yes") 'Verifies the Existance of the Radio Button and returns Boolean Value val = Obj.Exist print val 'Returns the Outerhtml of the Radio Button txt = Obj.GetROProperty("outerhtml") print text 'Returns the boolean value if Radio button is Visible. vis = Obj.GetROProperty("visible") print vis
使用组合框
以下是可以使用组合框的一些关键方法 –
-
Select(Value) – 帮助测试人员从 ComboBox 中选择值
-
单击–单击对象
-
WaitProperty – 等待直到属性值变为真
-
存在– 检查组合框的存在
-
GetROProperty(“Text”) – 获取组合框的选定值
-
GetROProperty(“all items”) – 返回组合框中的所有项目
-
GetROProperty(“items count”) – 返回组合框中的项目数
例子
'Get the List of all the Items from the ComboBox Set ObjList = Browser("Math Calculator").Page("Statistics").WebList("class") x = ObjList.GetROProperty("all items") print x 'Get the Number of Items from the Combo Box y = ObjList.GetROProperty("items count") print y 'Get the text value of the Selected Item z = ObjList.GetROProperty("text") print z
使用按钮
以下是一些可以使用按钮的关键方法 –
-
单击–单击按钮
-
WaitProperty – 等待直到属性值变为真
-
存在– 检查按钮是否存在
-
GetROProperty(“Name”) – 获取按钮的名称
-
GetROProperty(“Disabled”) – 如果启用/禁用,则返回布尔值
例子
'To Perform a Click on the Button Set obj_Button = Browser("Math Calculator").Page("SQR").WebButton("Calc") obj_Button.Click 'To Perform a Middle Click on the Button obj_Button.MiddleClick 'To check if the button is enabled or disabled.Returns Boolean Value x = obj_Button.GetROProperty("disabled") print x 'To fetch the Name of the Button y = obj_Button.GetROProperty("name") print y
使用 webTables
在当今基于 web 的应用程序中,webTables 已经变得非常普遍,测试人员需要了解 WebTables 是如何工作的以及如何在 webTables 上执行操作。本主题将帮助您有效地使用 webTables。
Sr.No. | 声明和说明 |
---|---|
1 |
if statement 一个如果语句由一个布尔表达式后跟一个或多个语句。 |
2 |
if…else statement 一,如果其他语句由一个布尔表达式后跟一个或多个语句。如果条件为真。执行if语句下的语句。如果条件为假。脚本的其他部分被执行 |
3 |
if..elseif…else statement 一个 if 语句后跟一个或多个Elseif语句,它由布尔表达式组成,然后是一个可选的else 语句,当所有条件变为假时执行。 |
4 |
nested if statements 另一个 if 或elseif语句中的if或elseif语句。 |
5 |
switch statement 甲开关语句允许一个变量以用于同等地检测aganist值的列表。 |
-
html id – 如果表格有一个 id 标签,那么最好使用这个属性。
-
innerText – 表格的标题。
-
sourceIndex – 获取表的源索引
-
ChildItemCount – 获取指定行中存在的 ChildItems 的数量
-
RowCount – 获取表中的行数
-
ColumnCount – 获取表中的列数
-
GetcellData – 根据列和行索引获取单元格的值
例子
Browser("Tutorials Point").Sync ' WebTable Obj = Browser("Tutorials Point").Page("VBScript Decisions").WebTable("Statement") ' Fetch RowCount x = Obj.RowCount print x ' Fetch ColumnCount y = Obj.ColumnCount(1) print y ' Print the Cell Data of the Table For i = 1 To x Step 1 For j = 1 To y Step 1 z = Obj.GetCellData(i,j) print "Row ID : " & i & " Column ID : " & j & " Value : " & z Next Next 'Fetch the Child Item count of Type Link in a particular Cell z = Obj.ChildItemCount(2,1,"Link") print z
QTP – 虚拟对象
什么是虚拟对象?
有时,被测应用程序可能包含标准窗口对象,但不被 QTP 识别。在这些情况下,可以将对象定义为按钮、链接等类型的虚拟对象(VO),以便在执行期间可以在虚拟对象上模拟用户操作。
例子
假设我们正在 Microsoft Word 中自动化一个场景。我激活了 MS Word 应用程序,然后单击功能区中的任何图标。例如,在功能区上,单击“插入”选项卡,然后用户单击“图片”按钮。按钮被识别为 WinObject;因此,虚拟对象的重要性是显而易见的。
Window("Microsoft Word").WinObject("Ribbon").Click 145,45 Window("Microsoft Word").WinObject("Ribbon").WinObject("Picture...").Click 170,104
创建虚拟对象
步骤 1 – 在这种情况下,使用虚拟对象管理器或从“工具”>>“虚拟对象”>>“新虚拟对象”创建新虚拟对象,然后单击“下一步”按钮创建虚拟对象。
第 2 步– 根据类类型映射对象,然后单击“下一步”。
步骤 3 – 单击“标记对象”按钮。将出现一个十字光标并标记您要映射的对象,然后单击“下一步”。
步骤 4 – 选择虚拟对象的父对象,然后单击“下一步”。
步骤 5 – 命名要存储虚拟对象的集合,然后单击“完成”。
虚拟对象管理器
虚拟对象管理器管理虚拟对象的集合。测试人员可以从虚拟对象管理器中添加或删除虚拟对象。
导航到虚拟对象管理器:“工具”>>“虚拟对象管理器”,如下所示 –
使用虚拟对象
创建虚拟对象后,可以使用创建的对象,如下所示 –
Window("Microsoft Word").WinObject("Ribbon").VirtualButton("button").Click
虚拟对象限制
-
QTP 不支持用于模拟或低级记录的虚拟对象。
-
不能在虚拟对象上添加检查点。
-
虚拟对象不受对象存储库控制。
-
虽然我们将一个对象映射到一个特定的类(按钮或列表),但虚拟对象并不支持原生对象的所有方法。
-
对象间谍不能用于虚拟对象。
-
如果屏幕分辨率随着坐标的变化而变化,则测试执行将失败。
-
应用程序窗口应具有相同的屏幕大小,以便正确捕获虚拟对象。
QTP – 访问数据库
因此,QTP 不提供任何内置支持连接到数据库,但是使用 VBScript 测试人员将能够使用 ADODB 对象连接和与数据库交互。
ADODB 有 4 个属性或方法,我们可以使用它们来处理数据库。他们是 –
-
ADODB.Connection – 用于建立与数据库的连接
-
ADODB.Command – 用于执行 SQL 命令(查询或存储过程)
-
ADODB.Fields – 用于在执行查询/存储过程后从记录集中获取特定列
-
ADODB.Recordset – 用于从数据库中获取数据
如何连接到数据库?
可以使用连接字符串连接数据库。每个数据库的连接方式都不同。但是,可以在www.connectionstrings.com的帮助下构建连接字符串
让我们看看如何使用以下参数连接到数据库 –
-
数据库类型– MSSQL SERVER
-
服务器名称– SQLEXPRESS
-
数据库名称– 试用
-
用户 ID – sa
-
密码– Password123
查询的输出显示在 SQL Server Management Studio 中,如下所示 –
Dim objConnection 'Set Adodb Connection Object Set objConnection = CreateObject("ADODB.Connection") Dim objRecordSet 'Create RecordSet Object Set objRecordSet = CreateObject("ADODB.Recordset") Dim DBQuery 'Query to be Executed DBQuery = "Select NAME from dbo.EMPLOYEE where AGE = 29" 'Connecting using SQL OLEDB Driver objConnection.Open "Provider = sqloledb.1;Server =.\SQLEXPRESS; User Id = sa;Password=Password123;Database = Trial" 'Execute the Query objRecordSet.Open DBQuery,objConnection 'Return the Result Set Value = objRecordSet.fields.item(0) msgbox Value ' Release the Resources objRecordSet.Close objConnection.Close Set objConnection = Nothing Set objRecordSet = Nothing
结果
执行上述脚本时,输出显示在消息框中,如下所示 –
QTP 使用 XML
XML 是一种标记语言,旨在以人机可读的格式存储数据。使用 XML,还可以轻松地在计算机和数据库系统之间交换数据。
示例 XML 及其关键元素如下所示 –
访问 XML
Const XMLDataFile = "C:\TestData.xml" Set xmlDoc = CreateObject("Microsoft.XMLDOM") xmlDoc.Async = False xmlDoc.Load(XMLDataFile) ' Getting the number of Nodes (books) Set nodes = xmlDoc.SelectNodes("/bookstore/book") Print "Total books: " & nodes.Length ' Displays 2 ' get all titles Set nodes = xmlDoc.SelectNodes("/Booklib/book/value/text()") ' get their values For i = 0 To (nodes.Length - 1) Title = nodes(i).NodeValue Print "Title is" & (i + 1) & ": " & Title Next
比较 XML
我们可以比较两个给定的 XML –
Dim xmlDoc1 Dim xmlDoc2 ' Load the XML Files Set xmlDoc1 = XMLUtil.CreateXMLFromFile ("C:\File1.xml") Set xmlDoc2 = XMLUtil.CreateXMLFromFile ("C:\File2.xml") 'Use the compare method of the XML to check if they are equivalent Comp = xmlDoc1.Compare (xmlDoc1, xmlDoc2) 'Returns 1 if the two files are the same If Comp = 1 Then Msgbox "XML Files are the Same" Else Msgbox "XML Files are Different" End if
QTP – 描述性编程
仅当对象存在于对象存储库中时,QTP 脚本才能执行。对象的描述是使用描述性编程创建的 –
-
当测试人员想要对对象存储库中不存在的对象执行操作时
-
当应用程序中的对象本质上非常动态时。
-
当对象存储库变大时,随着对象存储库大小的增加,导致性能变差。
-
构建框架时,已决定根本不使用对象存储库。
-
当测试人员想要在运行时对应用程序执行操作而不知道对象的唯一属性时。
句法
有两种使用描述性编程技术编写脚本的方法。他们是 –
- 描述对象
- 描述字符串
描述对象
脚本是使用描述对象开发的,这些对象依赖于所使用的属性及其相应的值。然后,这些描述用于构建脚本。
'Creating a description object Set btncalc = Description.Create() 'Add descriptions and properties btncalc("type").value = "Button" btncalc("name").value = "calculate" btncalc("html tag").value = "INPUT" ' Use the same to script it Browser("Math Calc").Page("Num Calculator").WebButton(btncalc).Click
描述字符串
对象的描述是使用属性和值作为字符串开发的,如下所示。
Browser("Math Calc").Page("Num Calculator").WebButton("html tag:=INPUT","type:=Button","name:=calculate").Click
子对象
QTP 提供了 ChildObjects 方法,它使我们能够创建对象的集合。父对象在子对象之前。
Dim oDesc Set oDesc = Description.Create oDesc("micclass").value = "Link" 'Find all the Links Set obj = Browser("Math Calc").Page("Math Calc").ChildObjects(oDesc) Dim i 'obj.Count value has the number of links in the page For i = 0 to obj.Count - 1 'get the name of all the links in the page x = obj(i).GetROProperty("innerhtml") print x Next
序数标识符
描述性编程用于根据序数标识符编写脚本,当两个或多个对象具有相同的属性时,这将使 QTP 能够对这些对象进行操作。
' Using Location Dim Obj Set Obj = Browser("title:=.*google.*").Page("micclass:=Page") Obj.WebEdit("name:=Test","location:=0").Set "ABC" Obj.WebEdit("name:=Test","location:=1").Set "123" ' Index Obj.WebEdit("name:=Test","index:=0").Set "1123" Obj.WebEdit("name:=Test","index:=1").Set "2222" ' Creation Time Browser("creationtime:=0").Sync Browser("creationtime:=1").Sync Browser("creationtime:=2").Sync
QTP – 自动化对象模型
QTP 本身可以使用 HP-QTP 提供的 COM 接口实现自动化。自动化对象模型是一组对象、方法和属性,可帮助测试人员使用 QTP 界面控制配置设置和执行脚本。下面列出了可以控制(但不限于)的关键配置/操作 –
- 加载测试所需的所有插件
- 在执行时使 QTP 可见
- 使用指定位置打开测试
- 关联函数库
- 指定公共对象同步超时
- 开始和结束迭代
- 启用/禁用智能识别
- 错误设置
- 数据表路径
- 恢复场景设置
- 日志跟踪设置
QTP 11.5x 提供了关于自动化对象模型的独家文档,可以通过导航到“开始”>>“所有程序”>>“HP 软件”>>“HP 统一功能测试”>>“文档”>>“Unified功能测试自动化参考”。
生成 AOM 脚本
测试人员可以使用“生成脚本”选项从 QTP 本身生成 AOM 脚本。导航到“运行”>>“设置”>>“属性”选项卡>>“生成脚本”,如下所示 –
例子
' A Sample Script to Demostrate AOM Dim App 'As Application Set App = CreateObject("QuickTest.Application") App.Launch App.Visible = True App.Test.Settings.Launchers("Web").Active = False App.Test.Settings.Launchers("Web").Browser = "IE" App.Test.Settings.Launchers("Web").Address = "http://easycalculation.com/" App.Test.Settings.Launchers("Web").CloseOnExit = True App.Test.Settings.Launchers("Windows Applications").Active = False App.Test.Settings.Launchers("Windows Applications").Applications.RemoveAll App.Test.Settings.Launchers("Windows Applications").RecordOnQTDescendants = True App.Test.Settings.Launchers("Windows Applications").RecordOnExplorerDescendants = False App.Test.Settings.Launchers("Windows Applications").RecordOnSpecifiedApplications = True App.Test.Settings.Run.IterationMode = "rngAll" App.Test.Settings.Run.StartIteration = 1 App.Test.Settings.Run.EndIteration = 1 App.Test.Settings.Run.ObjectSyncTimeOut = 20000 App.Test.Settings.Run.DisableSmartIdentification = False App.Test.Settings.Run.OnError = "Dialog" App.Test.Settings.Resources.DataTablePath = "<Default>" App.Test.Settings.Resources.Libraries.RemoveAll App.Test.Settings.Web.BrowserNavigationTimeout = 60000 App.Test.Settings.Web.ActiveScreenAccess.UserName = "" App.Test.Settings.Web.ActiveScreenAccess.Password = "" App.Test.Settings.Recovery.Enabled = True App.Test.Settings.Recovery.SetActivationMode "OnError" App.Test.Settings.Recovery.Add "D:\GUITest2\recover_app_crash.qrs", "Recover_Application_Crash", 1 App.Test.Settings.Recovery.Item(1).Enabled = True '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' System Local Monitoring settings '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' App.Test.Settings.LocalSystemMonitor.Enable = false '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Log Tracking settings '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' With App.Test.Settings.LogTracking .IncludeInResults = False .Port = 18081 .IP = "127.0.0.1" .MinTriggerLevel = "ERROR" .EnableAutoConfig = False .RecoverConfigAfterRun = False .ConfigFile = "" .MinConfigLevel = "WARN" End With
QTP – 框架
框架定义了一组指南/最佳实践,强制执行一组标准,这使得最终用户可以轻松使用。有不同类型的自动化框架,下面列出了最常见的框架 –
- 关键字驱动的框架
- 数据驱动框架
- 混合框架
关键字驱动的框架
关键字驱动测试是一种功能自动化测试框架,也称为表驱动测试或基于动作词的测试。
在关键字驱动的测试中,我们使用表格格式,通常是电子表格,为我们想要执行的每个功能定义关键字或操作词。
优点
-
它最适合新手或非技术测试人员。
-
允许使用这种方法以更抽象的方式编写测试。
-
关键字驱动测试允许在 SDLC 中更早地启动自动化,甚至在交付用于测试的稳定版本之前。
-
具有高度的可重用性。
缺点
-
开发关键字及其相关功能的初始投资可能需要更长的时间。
-
它可能会限制具有技术能力的测试人员。
数据驱动框架
数据驱动测试是创建测试脚本,其中从数据文件读取测试数据和/或输出值,而不是每次测试运行时使用相同的硬编码值。这样,测试人员可以测试应用程序如何有效地处理各种输入。它可以是以下任何数据文件 –
- 数据池
- Excel文件
- ADO 对象
- CSV 文件
- ODBC 源
流程图
下图可以最好地理解数据驱动测试 –
优点
- 数据驱动的框架导致代码量更少
- 为维护和修复脚本问题提供更大的灵活性
- 可开发测试数据
缺点
- 每个脚本都需要不同才能理解不同的数据集。
混合框架
混合框架是关键字驱动和数据驱动框架的组合,可以使用以下流程图进行最佳描述。
影响因素
以下是开发框架时应考虑的参数。下面列出了影响因素 –
-
框架文件应支持版本控制软件,如SVN、CVS、MS Source Control
-
框架应支持在不同环境中执行脚本,即 QA、SAT、DEV
-
在对象更改时,脚本应以最少的更改执行。
-
框架应该自行配置并处理先决条件,例如创建文件夹/数据库。
-
框架应该具有强大的报告结构,以便可以轻松发现脚本/应用程序中的问题
-
框架应该具有更大的灵活性,以便它应该易于使用
-
框架应遵循编码标准,以便正确维护文件、功能和更改历史记录。
在下一章中,我们将学习如何设计一个简单的框架。
QTP – 设计框架
让我们通过一个示例应用程序来设计一个简单的框架。我们将自动化测试应用程序的一些场景并编写可重用的功能。
测试中的示例应用程序是“计算器”,它是作为 Windows 的一部分提供的默认应用程序。现在让我们创建一个框架的不同组件。在这里,我们将开发一个混合框架并使用 Object Repository,因为它是一个相当简单的应用程序。但是,该框架也可以扩展以支持复杂的应用程序。
框架的文件夹结构如下所示 –
文件夹结构说明 –
-
Master Driver Script – 驱动整个执行的脚本。它执行执行所需的先决条件和初始设置。
-
库文件– 形成函数库的相关函数。
-
数据表– 执行所需的测试数据。
-
对象存储库– 使 QTP 能够无缝识别对象的对象及其属性。
-
执行日志– 该文件夹包含带有用户函数和函数执行历史的执行日志文件。
主驱动程序脚本
'= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ' MASTER DRIVER SCRIPT NAME : Calculator ' DESCRIPTION : Drivers Script to Execute Automated Test for the Calculator ' AUTHOR : Tutorials Point ' DATE CREATED : 30-Dec-2013 ' OBJECT REPOSITORY ASSOCIATED : Calc.tsr ' LIBRARY FILES ASSOCIATED : calculator.qfl, Common.qfl ' MODIFICATION LOG ' ---------------------------------------------------- ' First Version Tutorials point '= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = Option Explicit Public ExecDrive ' Get the Root folder of the Test so that we can make use of relative paths. Dim x : x = Instr(Environment.Value("TestDir"),"Driver")-2 ExecDrive = mid(Environment.Value("TestDir"),1,x) ' Get the path of Libraries using relative to the current Drive Dim LibPath : LibPath = ExecDrive+"\Libraries\" ' Dynamically Load the Function Libraries LoadFunctionLibrary LibPath + "Calculator.qfl", LibPath + "common_utils.qfl" ' Capturing the Start Time ' clscommon is the class object created in common.qfl library file clscommon.StartTime = Time() ' Launching the Application SystemUtil.Run "C:\Windows\System32\Calc.exe" : wait (2) ' Initialize the Data Table Path Dim FileName : FileName = ExecDrive+"\TestData\Calculator.xls" Dim SheetSource : SheetSource = "Calc_test" Dim SheetDest : SheetDest = "Global" ' Import the DataTable into the QTP Script DataTable.ImportSheet FileName , SheetSource , SheetDest ' Object Repository Path Dim RepPath : RepPath = ExecDrive+"\Object_Repository\Calc.tsr" RepositoriesCollection.RemoveAll() RepositoriesCollection.Add(RepPath) ' To Keep a Count on iteration Dim InttestIteration Dim InttestRows : InttestRows = datatable.GetRowCount ' Fetching Date-TimeStamp which will be unique for Naming the Execution Log File clscommon.StrDateFormatted = day(date()) & "_" & MonthName(Month(date()),true) & "_" & YEAR(date())& "_"&hour(now)&"_"&minute(now) ' Name the LogFile clscommon.StrLogFile = ExecDrive & "\Execution Logs\" & clscommon.StrDateFormatted & ".txt" ' Create the Execution LogFile which captures the result clscommon.Fn_FileCreate(clscommon.StrLogFile) ' Iniitialize the Parameters and all the relevant Test Details Call Fn_InitializeLogFile() ' Kill all the previous calculator process Call fn_Kill_Process("calc.exe") For InttestIteration = 1 to InttestRows datatable.SetCurrentRow InttestIteration Dim StrExecute : StrExecute = Ucase(Trim(datatable.Value("Run","Global"))) If StrExecute = "Y" Then clscommon.Number1 = Trim(datatable.Value("Number_1","Global")) clscommon.Number2 = Trim(datatable.Value("Number_2","Global")) clscommon.Number3 = Trim(datatable.Value("Number_3","Global")) clscommon.Number4 = Trim(datatable.Value("Number_4","Global")) clscommon.Number5 = Trim(datatable.Value("Number_5","Global")) clscommon.Number6 = Trim(datatable.Value("Number_6","Global")) clscommon.Test_Case_ID = Trim(datatable.Value("Test_Case_ID","Global"))' : clscommon.LogWrite "The Test Case Data is Located at :: " & tcDataPath clscommon.tcScenario = Trim(datatable.Value("Scenario","Global"))' : clscommon.LogWrite "The Test Case Data is Located at :: " & tcDataPath Dim Expected_Val : Expected_Val = Trim(datatable.Value("Expected_Val","Global"))' : clscommon.LogWrite "The Test Case Data is Located at :: " & tcDataPath Select case clscommon.tcScenario Case "Add" clscommon.LogWrite "=== Inside the Test Set :: " & clscommon.tcScenario & " ===" Call fnCalculate("+",Expected_Val) Case "Subtract" clscommon.LogWrite "=== Inside the Test Set :: " & clscommon.tcScenario & " ===" Call fnCalculate("-",Expected_Val) Case "Multiply" clscommon.LogWrite "=== Inside the Test Set :: " & clscommon.tcScenario & " ===" Call fnCalculate("*",Expected_Val) Case "Divide" clscommon.LogWrite "=== Inside the Test Set :: " & clscommon.tcScenario & " ===" Call fnCalculate("/",Expected_Val) Case "Sqrt" clscommon.LogWrite "=== Inside the Test Set :: " & clscommon.tcScenario & " ===" Call fnCalculate("sqt",Expected_Val) End Select End If Next ' Calling the End Test to Add the result Footer in exec log file. Call fn_End_test() ' ===================== End of Master Driver Script =====================
库文件
计算器函数写在一个单独的函数文件中,扩展名为 .qfl 或 .vbs。这些函数可以跨操作重用。
' Calculator. Qfl File :: Associated Function Library for Calculator Master Driver '= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ' FUNCTION NAME : Fn_InitializeLogFile ' DESCRIPTION : Function to Write the Initial Values in the Log File ' INPUT PARAMETERS : varExecDrive,StrDB,StrUId,Strpwd,StrNewDB ' OUTPUT PARAMETERS : NIL ' RETURN VALUE : Pass or Fail message ' DATE CREATED : 30-Dec-2013 '= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = Public Function Fn_InitializeLogFile() clscommon.LogWrite "********************************************" clscommon.LogWrite "Calc Automation Started" End Function '= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ' FUNCTION NAME : fnCalculate ' DESCRIPTION : Function to perform Arithmetic Calculations ' INPUT PARAMETERS : operator,Expected_Val ' OUTPUT PARAMETERS : NIL ' RETURN VALUE : Pass or Fail message ' DATE CREATED : 30-Dec-2013 '= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = Function fnCalculate(operator,Expected_Val) clscommon.LogWrite "Executing the Function 'fnCalculate' " Window("Calculator").Activate If Trim(clscommon.Number1) <> "" Then Window("Calculator").WinButton(clscommon.Number1).Click If Trim(clscommon.Number2) <> "" Then Window("Calculator").WinButton(clscommon.Number2).Click If Trim(clscommon.Number3) <> "" Then Window("Calculator").WinButton(clscommon.Number3).Click Window("Calculator").WinButton(operator).Click If Trim(clscommon.Number4) <> "" Then Window("Calculator").WinButton(clscommon.Number4).Click If Trim(clscommon.Number5) <> "" Then Window("Calculator").WinButton(clscommon.Number5).Click If Trim(clscommon.Number6) <> "" Then Window("Calculator").WinButton(clscommon.Number6).Click Window("Calculator").WinButton("=").Click Dim ActualVal : ActualVal = Window("Calculator").WinEdit("Edit").GetROProperty("text") clscommon.LogWrite "The Actual Value after the Math Operation is "& ActualVal If Trim(ActualVal) = Trim(Expected_Val) Then clscommon.WriteResult "Pass", clscommon.Test_Case_ID , clscommon.tcScenario , " Expected Value matches with Actual Value :: " & ActualVal Else clscommon.WriteResult "Fail", clscommon.Test_Case_ID , clscommon.tcScenario , " Expected Value - " & Expected_Val & " Does NOT matches with Actual Value :: " & ActualVal End If Window("Calculator").WinButton("C").Click If Err.Number <> 0 Then clscommon.LogWrite "Execution Error : The Error Number is :: " & Err.Number & " The Error Description is " & Err.Description Err.Clear End If clscommon.LogWrite "Exiting the Function 'fnCalculate' " End Function '= = = = = = = = = = = = = = = = = = = = = = = = = = = ' FUNCTION NAME : fn_Kill_Process ' DESCRIPTION : Function to Kill the process by name ' INPUT PARAMETERS : Application name to be killed ' OUTPUT PARAMETERS : NIL ' RETURN VALUE : NIL ' DATE CREATED : 30-Dec-2013 '= = = = = = = = = = = = = = = = = = = = = = = = = = = Function fn_Kill_Process(process) Dim strComputer , strProcessToKill , objWMIService , colProcessstrComputer = "." strProcessToKill = process Set objWMIService = GetObject("winmgmts:" _& "{impersonationLevel=impersonate}!\\" _& strComputer & "\root\cimv2") Set colProcess = objWMIService.ExecQuery _("Select * from Win32_Process Where Name = '" & strProcessToKill & "'") count = 0 For Each objProcess in colProcess objProcess.Terminate() count = count + 1 Next End Function '= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ' FUNCTION NAME : fn_End_test ' DESCRIPTION : Function to finish the test Execution process ' INPUT PARAMETERS : Application name to be killed ' OUTPUT PARAMETERS : NIL ' RETURN VALUE : NIL ' DATE CREATED : 20/Dec/2013 '= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = Function fn_End_test() clscommon.LogWrite "Status Message - Executing the Function 'fn_End_test' " Window("Calculator").Close On Error Resume Next clscommon.StopTime = Time() clscommon.ElapsedTime = DateDiff("n",clscommon.StartTime,clscommon.StopTime) Dim Totaltests Totaltests = clscommon.gintPassCount+ clscommon.gintFailCount clscommon.LogWrite "## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # clscommon.LogWrite "## The Execution Start Time :: " & clscommon.StartTime clscommon.LogWrite "## The Execution End Time :: " & clscommon.StopTime clscommon.LogWrite "## The Time Elapsed :: " & clscommon.ElapsedTime & " Minutes " clscommon.LogWrite "## The OS :: " & Environment.Value("OS") clscommon.LogWrite "## The Total No of Test Cases Executed :: " & Totaltests clscommon.LogWrite "## The No. of Test Case Passed :: " & clscommon.gintPassCount clscommon.LogWrite "## The No. of Test Case Failed :: " & clscommon.gintFailCount clscommon.LogWrite "## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # SystemUtil.CloseDescendentProcesses End Function ' =============== End of Calculator. Qfl ============================= '
另一个库文件是包含函数的“common_utils.qfl”,它使我们能够将输出写入文本文件。
Set clscommon = New OS_clsUtils 'Creating a class file to handle global variables. Class OS_clsUtils Dim StrLogFile Dim StrDateFormatted Dim Result Dim Number1, Number2 , Number3 Dim Number4, Number5 , Number6 Dim Test_Case_ID , tcScenario Dim StartTime, StopTime, ElapsedTime Dim gintPassCount , gintFailCount , gintWarningCount , gintdoneCount, gintinfoCount Function Fn_FileCreate(strFileName) Dim objFSO: Set objFSO = CreateObject("Scripting.FileSystemObject") On Error Resume Next Dim objTextFile : Set objTextFile = objFSO.CreateTextFile(strFileName) objTextFile.Close Set objTextFile = Nothing Set objFSO = Nothing End Function Function LogWrite(sMsg) Const ForAppending = 8 Dim objFSO : Set objFSO = CreateObject("scripting.FileSystemObject") Dim objTextFile : Set objTextFile = objFSO.OpenTextFile (clscommon.StrLogFile, ForAppending, True) objTextFile.WriteLine day(date()) & "/" & MonthName(Month(date()),true) & "/" & YEAR(date()) & " " & time & ": " & sMsg objTextFile.Close Set objTextFile = Nothing Set objFSO = Nothing End Function Function WriteResult(strStatus,functionName,functionDescription,Result) Const ForAppending = 8 Dim objFSO : Set objFSO = CreateObject("scripting.FileSystemObject") Dim objTextFile : Set objTextFile = objFSO.OpenTextFile (clscommon.StrLogFile, ForAppending, True) objTextFile.WriteLine day(date()) & "/" & MonthName(Month(date()),true) & "/" & YEAR(date()) & " " & time & ": " & " * * * * * * Test Case Exec Details * * * * * " objTextFile.WriteLine day(date()) & "/" & MonthName(Month(date()),true) & "/" & YEAR(date()) & " " & time & ": " & " Test staus :: " & strStatus objTextFile.WriteLine day(date()) & "/" & MonthName(Month(date()),true) & "/" & YEAR(date()) & " " & time & ": " & " Tese ID :: " & functionName objTextFile.WriteLine day(date()) & "/" & MonthName(Month(date()),true) & "/" & YEAR(date()) & " " & time & ": " & " Test Description :: " & functionDescription objTextFile.WriteLine day(date()) & "/" & MonthName(Month(date()),true) & "/" & YEAR(date()) & " " & time & ": " & " Test Result Details :: " & Result objTextFile.WriteLine day(date()) & "/" & MonthName(Month(date()),true) & "/" & YEAR(date()) & " " & time & ": " & " * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * " objTextFile.Close Set objTextFile = Nothing Set objFSO = Nothing Select Case Lcase(strStatus) Case "pass" gintPassCount = gintPassCount + 1 Case "fail" gintFailCount = gintFailCount+1 End Select End Function End Class ' ===================== End of common_Utils.qfl =====================
对象库
Object Repository 已经获得了用户将要操作的所有对象。下面给出的图像显示了添加到存储库中的名称为 calc.tsr 的所有对象的列表
数据表
DataTable 包含关键字,它们驱动测试并测试 QTP 将用于对象的数据。
执行日志
执行日志文件或输出文件包含用户操作和功能日志,这将使测试人员能够在脚本失败时进行调试。
8/Jan/2014 5:09:16 PM: ************************************************* 8/Jan/2014 5:09:16 PM: Calc Automation Started 8/Jan/2014 5:09:16 PM: === Inside the Test Set :: Add === 8/Jan/2014 5:09:16 PM: Executing the Function 'fnCalculate' 8/Jan/2014 5:09:17 PM: The Actual Value after the Math Operation is 949. 8/Jan/2014 5:09:17 PM: * * * * * * Test Case Exec Details * * * * * 8/Jan/2014 5:09:17 PM: Test staus :: Pass 8/Jan/2014 5:09:17 PM: Tese ID :: TC_001 8/Jan/2014 5:09:17 PM: Test Description :: Add 8/Jan/2014 5:09:17 PM: Test Result Details :: Expected Value matches with Actual Value :: 949. 8/Jan/2014 5:09:17 PM: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 8/Jan/2014 5:09:17 PM: Exiting the Function 'fnCalculate' 8/Jan/2014 5:09:17 PM: === Inside the Test Set :: Subtract === 8/Jan/2014 5:09:17 PM: Executing the Function 'fnCalculate' 8/Jan/2014 5:09:17 PM: The Actual Value after the Math Operation is 415. 8/Jan/2014 5:09:17 PM: * * * * * * Test Case Exec Details * * * * * 8/Jan/2014 5:09:17 PM: Test staus :: Pass 8/Jan/2014 5:09:17 PM: Tese ID :: TC_002 8/Jan/2014 5:09:17 PM: Test Description :: Subtract 8/Jan/2014 5:09:17 PM: Test Result Details :: Expected Value matches with Actual Value :: 415. 8/Jan/2014 5:09:17 PM: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 8/Jan/2014 5:09:17 PM: Exiting the Function 'fnCalculate' 8/Jan/2014 5:09:17 PM: === Inside the Test Set :: Multiply === 8/Jan/2014 5:09:17 PM: Executing the Function 'fnCalculate' 8/Jan/2014 5:09:18 PM: The Actual Value after the Math Operation is 278883. 8/Jan/2014 5:09:18 PM: * * * * * * Test Case Exec Details * * * * * 8/Jan/2014 5:09:18 PM: Test staus :: Pass 8/Jan/2014 5:09:18 PM: Tese ID :: TC_003 8/Jan/2014 5:09:18 PM: Test Description :: Multiply 8/Jan/2014 5:09:18 PM: Test Result Details :: Expected Value matches with Actual Value :: 278883. 8/Jan/2014 5:09:18 PM: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 8/Jan/2014 5:09:18 PM: Exiting the Function 'fnCalculate' 8/Jan/2014 5:09:18 PM: === Inside the Test Set :: Divide === 8/Jan/2014 5:09:18 PM: Executing the Function 'fnCalculate' 8/Jan/2014 5:09:19 PM: The Actual Value after the Math Operation is 3. 8/Jan/2014 5:09:19 PM: * * * * * * Test Case Exec Details * * * * * 8/Jan/2014 5:09:19 PM: Test staus :: Pass 8/Jan/2014 5:09:19 PM: Tese ID :: TC_004 8/Jan/2014 5:09:19 PM: Test Description :: Divide 8/Jan/2014 5:09:19 PM: Test Result Details :: Expected Value matches with Actual Value :: 3. 8/Jan/2014 5:09:19 PM: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 8/Jan/2014 5:09:19 PM: Exiting the Function 'fnCalculate' 8/Jan/2014 5:09:19 PM: === Inside the Test Set :: Sqrt === 8/Jan/2014 5:09:19 PM: Executing the Function 'fnCalculate' 8/Jan/2014 5:09:20 PM: The Actual Value after the Math Operation is 10. 8/Jan/2014 5:09:20 PM: * * * * * * Test Case Exec Details * * * * * 8/Jan/2014 5:09:20 PM: Test staus :: Pass 8/Jan/2014 5:09:20 PM: Tese ID :: TC_005 8/Jan/2014 5:09:20 PM: Test Description :: Sqrt 8/Jan/2014 5:09:20 PM: Test Result Details :: Expected Value matches with Actual Value :: 10. 8/Jan/2014 5:09:20 PM: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 8/Jan/2014 5:09:20 PM: Exiting the Function 'fnCalculate' 8/Jan/2014 5:09:20 PM: Status Message - Executing the Function 'fn_Finish_test' 8/Jan/2014 5:09:20 PM: ## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 8/Jan/2014 5:09:20 PM: ## The Execution Start Time :: 5:09:14 PM 8/Jan/2014 5:09:20 PM: ## The Execution End Time :: 5:09:20 PM 8/Jan/2014 5:09:20 PM: ## The Time Elapsed :: 0 Minutes 8/Jan/2014 5:09:20 PM: ## The OS :: Microsoft Windows Vista Server 8/Jan/2014 5:09:20 PM: ## The Total No of Test Cases Executed :: 25 8/Jan/2014 5:09:20 PM: ## The No. of Test Case Passed :: 25 8/Jan/2014 5:09:20 PM: ## The No. of Test Case Failed :: 8/Jan/2014 5:09:20 PM: ## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #