Qtp 简明教程

QTP - Quick Guide

QTP - Introduction

QTP 表示 Q*uick*T*est *P*rofessional, a product of *H*ewlett *P*ackard *(HP) 。该工具可帮助测试人员在完成脚本开发后,无缝执行自动化功能测试,而无需监控。

HP QTP 使用 Visual Basic Scripting (VBScript) 来自动化应用程序。无需专门安装脚本引擎,因为它作为 Windows 操作系统的一部分提供。VBScript 的当前版本是 5.8,可作为 Win 7 的一部分提供。VBScript 不是面向对象语言,而是基于对象的语言。

Testing Tools

从软件测试上下文来看,工具可以定义为支持从规划、要求、创建构建、测试执行、缺陷记录和测试分析等一项或多项测试活动的产品。

Classification of Tools

可基于几个参数对工具进行分类。其中包括-

  1. 工具的用途

  2. 工具支持的活动

  3. 它支持的测试类型/级别

  4. 许可类型(开源、免费、商业)

  5. The technology used

Types of Tools

Sr.No.

Tool Type

Used for

Used by

1

Test Management Tool

测试 管理、调度、缺陷记录、跟踪和分析

Testers

2

Configuration management tool

用于实施、执行、跟踪变更

All Team members

3

Static Analysis Tools

Static Testing

Developers

4

Test data Preperation Tools

分析和设计、测试数据生成

Testers

5

Test Execution Tools

Implementation, Execution

Testers

6

Test Comparators

比较预期结果和实际结果

All Team members

7

Coverage measurement tools

Provides structural coverage

Developers

8

Performance Testing tools

监控性能、响应时间

Testers

9

项目计划和跟踪工具

For Planning

Project Managers

10

Incident Management Tools

For managing the tests

Testers

Where QTP Fits in?

QTP 是一款功能测试工具,非常适合测试应用程序的回归测试。QTP 是 HP 拥有的一款授权/商业工具,是市场上最流行的工具之一。它比较实际结果和预期结果,并在执行摘要中报告结果。

QTP – History and Evolution

惠普快速测试专业版最初由 Mercury Interactive 拥有,后来被 HP 收购。它最初的名称是 Astra Quick Test,后来命名为 Quick Test Professional,但最新版本称为 Unified Functional Tester (UFT)。

Version History

现在让我们来看一下 QTP 的版本历史。

Versions

Timelines

Astra Quick Test v1.0 至 v5.5 - Mercury Interactive

1998 年 5 月至 2001 年 8 月

QuickTest Professional v6.5 到 v9.0 - Mercury Interactive

2003 年 9 月至 2006 年 4 月

Hp-QuickTest Professional v9.1 到 v11.0 - 由惠普收购并发布

2007 年 2 月至 2010 年 9 月

Hp-Unified Functional Testing v11.5 到 v11.53

2012 to Nov 2013

Advantages

  1. 使用 VBScript 开发自动测试不要求高级编码人员,并且与其他面向对象的编程语言相比,相对容易。

  2. 使用简单、易于导航、结果验证和生成报告。

  3. 与测试管理工具 (Hp-Quality Center) 轻松集成,从而能够轻松调度和监控。

  4. 还可用于移动应用程序测试。

  5. 由于它是惠普产品,因此惠普及其论坛提供完全支持以解决技术问题。

Disadvantages

  1. 与 Selenium 不同,QTP 仅适用于 Windows 操作系统。

  2. 并非所有版本的浏览器都受支持,并且测试人员需要等待针对每个主要版本发布补丁。

  3. 话说回来,它是一种商业工具,因此许可费用非常高。

  4. 即使脚本时间较少,但执行时间相对较长,因为它会给 CPU 和 RAM 施加负载。

QTP - Automated Testing Process

对于任何自动工具实现,以下是其阶段/步骤。每个阶段都对应于一个特定的活动,每个阶段都有一个明确的结果。

automation testing process
  1. Test Automation Feasibility Analysis - 第一步是检查应用程序是否可以自动化。并非所有应用程序都可自动化,原因是其局限性。

  2. Appropriate Tool Selection - 下一个最重要的步骤是选择工具。这取决于应用程序构建所用的技术、其功能和用途。

  3. Evaluate the suitable framework - 在选择工具后,下一个活动是选择合适的框架。有各种框架,每个框架都有其自身的意义。我们将在本教程后面详细讨论框架。

  4. Build Proof of Concept - 概念验证 (POC) 开发了一个端到端场景,以评估该工具是否可以支持应用程序的自动化。它使用端到端场景执行,该场景确保可以自动化主要功能。

  5. Develop Automation Framework - 构建 POC 后,就会进行框架开发,这是任何测试自动化项目成功的关键步骤。应该在对应用程序使用的技术以及它的主要特征进行仔细分析后构建框架。

  6. Develop Test Script, Execute, and Analyze - 一旦脚本开发完成,就会执行脚本,分析结果并记录缺陷(如果有)。测试脚本通常受版本控制。

QTP - Environment SetUp

QTP 是一个商业工具,您可以直接从惠普网站下载试用版。只有当前版本 Unified Functional Testing(11.5x)可以下载。以下是下载试用版的网址。

下载 URL − QTP

Installation Procedure

Step 1 − 单击“试用版和演示版”链接,然后选择“HP Unified Functional Testing 11.50 CC English SW E-Media Evaluation”,如下所示:

download Install step1

Step 2 − 选择“HP Unified Functional Testing 11.50”后,将打开下载向导。填写个人详细信息,然后单击“下一步”。

download Install step2

Step 3 -阅读“使用条款”,然后点击“下一步”。

download Install step3

Step 4 -下载窗口打开。现在,点击“下载”按钮。

download Install step4

Step 5 -下载的文件格式为.RAR。现在,您需要解压该存档文件,文件夹内容将如下图所示,执行 Setup.exe。

download Install step5

Step 6 -执行安装文件后,为了安装,从列表中选取“统一功能测试设置”,如下图所示。

download Install step6

Step 7 -然后点击“下一步”以继续。

download Install step7

Step 8 -在定制设置窗口中,选取自动化所需的插件,即您应该根据测试应用程序的技术选取插件。例如,如果您的应用程序基于.NET,那么您应该确保选取.NET。

download Install step8

Step 9 -选取安装所需的插件后,点击“下一步”。安装完成后,您会看到一个“完成”按钮窗口。

download Install step10

Step 10 -安装完成后,“其他安装要求”对话框框打开。除“运行许可证安装向导”外,选取列表中的所有内容,然后点击“运行”。我们无须选取“运行许可证安装向导”,因为我们安装的是试用版,它默认提供 30 天许可证。

download Install step11

Step 11 -在其他安装要求完成后,会显示一个对勾标记,这说明组件已成功安装。现在,点击“关闭”。

download Install step12

Launching UFT and Add ins Page

Step 1 -安装后,可以从开始菜单启动应用程序,如下图所示。

download Install step13

Step 2 -许可证页面出现。我们可以点击“继续”,因为我们已经安装了试用许可证。

download Install step14

Step 3 -出现加载项对话框框,供用户选取所需的加载项。

Note -不要加载所有加载项,仅加载所需的加载项,然后点击“确定”。

download Install step15

Step 4 -加载所需加载项后,UFT 11.5 工具对用户打开,UFT 的第一眼印象如下所示:

download Install step16

QTP - Record and Playback

记录测试相当于记录被测应用程序的用户操作,以便 UFT 自动生成可以播放的脚本。如果初始设置完成正确,则记录和回放可以让我们初步了解该工具,以及它是否能支持该技术。

记录和回放的步骤如下 -

Step 1 − 如下所示,从主页中单击“新建”测试 -

qtp record and run settings step1

Step 2 − 单击“新建”链接时,将打开一个新的测试窗口,并且用户需要选择测试类型。选择“GUI 测试”,为测试命名,并选择需要保存它的位置。

qtp record and run settings step2

Step 3 − 创建新测试后,将打开新的测试屏幕,如下所示。现在,单击默认创建有 1 个操作的“Action1”选项卡。

qtp record and run settings step3

Step 4 − 单击“录制”菜单,然后选择“录制和运行设置”,如下所示 -

qtp record and run settings step4

Step 5 − 将打开录制和运行设置对话框,并且根据应用程序的类型,可以选择 Web、Java 或 Windows 应用程序。例如,此处,我们将录制一个基于 Web 的应用程序 ([role="bare"] [role="bare"]http://easycalculation.com/ )。

qtp record and run settings step5

Step 6 − 单击录制。Internet Explorer 会根据设置自动打开 Web 地址 https://www.easycalculation.com/ 。单击“代数”下的“数字”链接,并且输入一个数字并点击“计算”。完成该操作后,单击录制面板中的“停止”按钮。您将注意到生成以下脚本:-

qtp record and run settings step6

Step 7 − 现在,通过单击回放按钮回放脚本。脚本回放,并且结果显示出来。

qtp record and run settings step7

Step 8 − 结果窗口默认打开,它准确显示执行、通过和失败步骤的时间戳。

qtp record and run settings step8

Significance of Record and Playback

  1. 它用作初步调查方法,以验证 UFT 是否可以支持该技术/应用程序。

  2. 用于创建一个不需要长期维护的应用程序或功能的基本功能测试。

  3. 它可用于记录鼠标移动和键盘输入。

Modes of Recording

  1. Normal Recording − 这是默认录制模式,用于记录对被测应用程序执行的对象和操作。

  2. Analog Recording − 这不仅可以记录键盘操作,还可以记录相对于屏幕或应用程序窗口的鼠标移动。

  3. Low-Level Recording − 这将记录对象的准确坐标,而不管 UFT 是否识别该对象。它只记录坐标,因此不会记录鼠标移动。

  4. Insight Recording − UFT 根据操作的外观而不是根据它的本机属性记录操作。

How to Choose Recording Modes

在单击录制按钮后,一旦录制开始,用户便可以在屏幕上出现的录制窗格中选择录制模式。可以从上述讨论过的模式中进行选择。

qtp choosing recording modes

您将会看到,以下场景记录在所有模式中,并且同一样例记录在各种情况下。

  1. Launch IE - https://www.easycalculation.com/

  2. Click "Numbers" under "Algebra"

  3. Click "Square Root" link

  4. 输入一个值 để 计算平方根。我们假设为 10

  5. Hit Calculate

在默认、模拟和低级记录模式下记录的脚本如下 −

' 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

使用 Insight 记录模式的记录如下 −

recording mode comparison

QTP - Object Repository

Object Repository

对象存储库是对象和属性的集合,QTP 可以识别这些对象并作用于它们。当用户记录测试时,会默认捕获对象及其属性。如果不了解对象及其属性,QTP 将无法回放脚本。

单击以下每个主题,以详细了解对象存储库及其相关功能。

Sr.No.

Topic & Description

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

Functions

操作是 QTP 的内置特性。

QTP 和 VBScript 支持 VBScript 函数。

操作参数仅按值传递。

函数参数通过按值或引用传递。

Actions have extension .mts

函数保存为 .vbs 或 .qfl

操作可重复使用,也可不重复使用。

Functions are always reusable.

可以通过右键单击脚本编辑器窗口并选择“属性”,访问操作的属性。

qtp actions 1

操作属性包括以下信息-

  1. Action Name

  2. Location

  3. Reusable Flag

  4. Input Parameters

  5. Output Parameters

Types of Actions

共有三种类型的操作-

  1. Non-reusable action - 只能在其被设计的那项特定测试中调用的操作,且只能调用一次。

  2. Reusable action - 可以多次调用,它存在的任何测试中,并且还可以被任何其他测试使用。

  3. External Reusable action - 存储在另一个测试中的可重用操作。外部操作在调用测试中是只读的,但可以使用外部操作的数据表信息的编辑副本在本地使用它。

Working with Actions

有三种方法来插入操作。单击其中任何一个了解更多有关所选操作类型的信息。

Sr.No.

Action Type & Description

1

Insert Call to New Action 从现有操作插入新的操作

2

Insert Call to Copy of Action 插入现有操作的副本

3

Insert Call to Existing Action 插入对现有可重用操作的调用

QTP - Datatables

数据表(类似于 Microsoft Excel)帮助测试者创建可以用于多次运行操作的数据驱动测试用例。有两种数据表 −

  1. Local DataTable − 每个操作都有自己的私有数据表,也称为本地数据表,还可以跨操作访问该数据表。

  2. Global DataTable − 每个测试都有一个全局数据表,可跨操作访问该数据表。

数据表可以从 QTP 的“数据”选项卡中访问,如下所示 −

qtp datasheet 1

要对指定的迭代次数执行一个测试用例,可以在测试设置对话框中设置全局数据表的迭代,可以通过文件→设置→运行(选项卡)访问,如下所示 -

qtp datasheet 3

Example

例如,如果用户希望对可以通过 http://easycalculation.com/compound-interest.php 访问的“复合利息” http://easycalculation.com/ 进行参数化。可以创建参数,如下所示。数据表中也可以使用 Excel 的大多数功能。

qtp datasheet 2

DataTable Operations

有三种类型的对象可以访问 DataTable。DataTable 操作可以通过遍历以下内容来很好地理解 -

Sr.No.

Object Type & Description

1

Data Table Methods 提供有关数据表方法的详细信息。

2

DTParameter Object Methods 提供有关 DTParameter 方法的详细信息。

3

DTSheet Object Methods 提供有关 DTSheet 方法的详细信息。

QTP - CheckPoints

如名称所述,检查点是指将当前值指定属性或对象的当前状态与预期值相比较的验证点,可以插入到脚本中的任何时间点。

Types of Checkpoints

Sr.No.

Type & Description

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) 网页内容无障碍指南的部分

8

Page Checkpoint 核对网页的特性。它还可以检查损坏的链接。

9

Database Checkpoint 核对被测试应用程序访问的数据库的内容。

10

XML Checkpoint 核对网页和框架中 .xml 文档或 .xml 文档的内容。

Inserting CheckPoint

当用户想要插入一个检查点时,必须确保在录制期间仅支持大多数检查点。一旦用户停止录制,检查点将不可用。

以下是在非录制模式下,检查点菜单。

qtp checkpoint before recording

以下是在录制模式下,检查点菜单。

qtp checkpoint after recording 1

Example

可为测试应用程序添加检查点 — “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

Viewing Checkpoint Properties

插入后,如果测试人员想要更改值,可以通过右键单击脚本中的关键字“检查点”并导航到“检查点属性”以进行更改,如下所示 −

qtp checkpoint after recording 2

您还可以在对象储存库中找到相同的检查点,如下所示。它准确显示了使用哪种类型的检查点、期望值和超时值。

qtp checkpoint after recording 3

QTP - Synchronization

同步点是待测试工具和应用程序之间的时序接口。同步点是一项用于指定测试脚本的两个步骤之间延迟时间的特性。

例如,单击一个链接可能在 1 秒内加载页面,有时候需要 5 秒,甚至可能需要 10 秒才能完全加载。这取决于各种因素,例如应用程序服务器响应时间、网络带宽和客户端系统功能。

如果时间不一致,则脚本将失败,除非测试人员智能地处理这些时间差异。

Ways to Insert Sync Point

  1. WaitProperty

  2. Exist

  3. Wait

  4. Sync(仅适用于基于 Web 的应用)

  5. 插入 QTP 固有的一致性点

假设我们在 “@{}” 中单击“数字”链接和单击“简单利息”计算器之间需要插入一个同步点。对于上述场景,我们将研究插入同步点的五种方式。

Method 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

Method 2 − Exist

Exist 是一种方法,将超时值作为输入以执行同步。它也是一个动态等待,因此建议使用此选项。

' 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

Method 3 − Wait

Wait 是一个硬编码的同步点,与事件是否发生无关的等待。因此,不建议使用 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

Method 4 − Sync Method

同步方法仅可用于页面加载之间始终存在延迟的 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

Method 5 − Inserting QTP Inbuilt Synchronization points

@{}− 进入记录模式。如果用户不在记录模式内,此选项将被禁用。

@{}− 转到“设计”→“同步点”。

@{}− 我们需要选择要作为同步点的对象。在选择该对象后,会像下面所示打开一个对象窗口 −

qtp sync point 1

@{}− 单击“确定”,将打开“添加同步窗口”。选择“属性”、“值”和“超时”值,然后单击“确定”,如以下所示 −

qtp sync point 2

@{}− 会生成如下图所示的脚本,它与我们之前讨论过的 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

Default Synchronization

当用户未对上述任何一种同步方法使用任何方法时,QTP 仍可使用用户可以调整的固有的对象同步超时。

导航至“文件”>> “设置”>> “运行”选项卡 >> “对象同步超时”,如以下所示。

qtp sync point 3

QTP - Smart Identification

有时,QTP 无法找到与识别的对象描述相匹配的任何对象,或者它可能会找到多个适合该描述的对象,然后 QTP 将忽略识别的描述并使用智能识别机制识别对象。

QTP 的智能识别使用两种类型的属性 -

  1. Base Filter Properties - 特定测试对象类的基本属性,在不改变原始对象的本质的情况下无法更改其值。

  2. Optional Filter Properties - 其他属性也有助于识别特定类的对象,其属性不太可能经常更改,但如果不再适用,则可以忽略。

Enabling Smart Identification for an Object

Step 1 - 导航到“工具”→“对象识别”。对象识别对话框打开。

Step 2 - 选择环境、对象类并打开“启用智能识别”,如下所示 -

qtp smart identification

Step 3 - 单击“配置”并选择基础和可选筛选器属性。

qtp smart identification 1

Step 4 - 在基础属性中添加除默认属性之外的属性,还可以添加/删除可选筛选器属性。请注意,相同的属性不能同时属于强制属性和辅助属性,然后单击“确定”。

qtp smart identification 2

Step 5 - 在对象存储库中添加该类型对象后,验证是否启用智能识别。智能识别已设置为 TRUE。在不需要启用智能识别的情况下,也可以将其设置为 False。

qtp smart identification 3

Step 6 - 甚至可以通过在“文件”菜单的“设置”下应用测试脚本级别来禁用测试级别,如下所示:

qtp smart identification 4

Step 7 - 如果根据步骤 6 禁用智能识别,它将在脚本执行期间不会对任何对象应用智能识别。

Step 8 - 如果使用关闭状态添加对象,则 QTP 将不会使用智能识别来进行识别,即使我们稍后已将其启用。

QTP - Debugging

在自动化测试环境中,调试是对自动化脚本中的编码问题进行识别和修复的一个系统性过程,以便脚本更加稳健,并可以在应用程序中识别缺陷。

使用 QTP 中的断点有各种执行调试的方法。只需按“F9”或使用菜单选项“运行”→“插入/删除断点”即可插入断点。

插入断点后,“红色”点和行将突出显示为红色,如下所示 −

qtp debugging

Method

ShortCut

Description

Step Into

F11

用于执行每个步骤。逐步进入函数/操作并逐行执行。它在执行后在每行暂停。

Step Over

F10

用于跨过函数。跨过只运行活动文档中的当前步骤。

Step Out

Shift+F11

逐步进入函数后,你可以使用“逐步离开”命令。逐步离开继续运行到函数结束,然后在下一行暂停运行会话。

Options in Break Point

可以通过导航“运行”菜单访问断点中的各种选项。

Sr.No.

ShortCut & Description

1

F9 Insert/Remove BreakPoint

2

Ctrl+F9 Enable/Disable BreakPoint

3

Ctrl+Shift+F9 Clear All BreakPoint

4

Use Only Menu 启用/禁用所有断点

Debugging Pane

调试窗口中的窗格如下 −

qtp debugging 3
  1. Output − 此选项卡显示打印语句的所有输出。

  2. Watch − 此选项卡显示给定表达式的布尔输出。

  3. LocalVariables − 此选项卡显示本地变量的输出。

Example

监视窗格显示输出表达式,如下所示 −

qtp debugging 2

本地变量窗格显示本地变量保存的值,如下所示 −

qtp debugging 4

QTP - Error Handling

在 QTP 中处理错误有多种方法。在使用 QTP 时,可能遇到三种可能的错误类型:

  1. Syntax Errors

  2. Logical Errors

  3. Run Time Errors

Error Types

Syntax Errors

语法错误是与 VBScript 语言语法不符的错误或代码片段。语法错误发生在代码编译时,在这些错误得到修复之前无法执行。

若要验证语法,可以使用键盘快捷键 Ctrl+F7,结果显示在下边。如果窗口未显示,则可以导航至“视图”→“错误”。

qtp error handling 1

Logical Errors

如果脚本的语法正确,但是生成了意外的结果,则称为逻辑错误。逻辑错误通常不会中断执行,但是会生成错误的结果。逻辑错误可能由于各种原因导致,例如:错误的假设或需求错误理解,有时还会产生错误的程序逻辑(使用 do-while 代替 do-Until)或无限循环。

检测逻辑错误的一种方法是进行同行评审,还要验证 QTP 输出文件/结果文件,以确保该工具按预期方式执行。

RunTime Errors

顾名思义,此类错误发生在运行时。此类错误的原因是脚本尝试执行某项操作但无法执行,而且脚本通常停止执行,因为它无法继续执行。运行时错误的经典示例是:

  1. 文件不存在,但脚本尝试读取该文件

  2. 对象不存在,但脚本尝试针对该特定对象执行操作

  3. 将数字除以零

  4. 访问数组元素时,数组索引超出界限

Handling Run-Time Errors

处理代码中错误有多种方法。

1. Using Test Settings - 可以通过导航至“文件”>>“设置”>>“运行”选项卡来在测试设置中定义错误处置,如下所示。我们可以选择任何指定设置,然后单击“确定”。

qtp error handling 2

2. Using On Error Statement - 测试者可以将“On Error”语句用于通知 VBScript 引擎其打算处理运行时错误,而不是允许 VBScript 引擎显示用户不友好的错误消息。

  1. On Error Resume Next - On Error Resume Next 会通知 VBScript 引擎当遇到错误时处理执行下一行代码。

  2. On error Goto 0 - 这有助于测试人员关闭错误处理。

3. Using Err Object - 错误对象是 VBScript 内的一个内置对象,可以捕获我们能够方便调试代码的运行时错误编号和错误描述。

  1. Err.Number - Number 属性返回或设置一个指定错误的数字值。如果 Err.Number 值为 0,则表示未发生错误。

  2. Err.Description - Description 属性返回或设置一个关于错误的简要描述。

  3. Err.Clear - Clear 方法会重置错误对象,并清除与其关联的所有先前值。

Example

'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. Using Exit Statement − Exit 语句可以与 Err 对象结合使用,以基于 Err.Number 值退出测试、操作或迭代。让我们详细了解每个 Exit 语句。

  1. ExitTest − 不管运行时迭代设置是什么,退出整个 QTP 测试。

  2. ExitAction − 退出当前操作。

  3. ExitActionIteration − 退出操作的当前迭代。

  4. ExitTestIteration − 退出 QTP 测试的当前迭代,并继续执行下一个迭代。

5. Recovery Scenarios − 遇到错误时,基于特定条件触发恢复场景,并在单独的章节中详细介绍。

6. Reporter Object − Reporter 对象帮助我们将事件报告给运行结果。它帮助我们识别相关的操作/步骤是通过/失败。

'Syntax: Reporter.ReportEventEventStatus, ReportStepName, Details,
[ImageFilePath]

'Example
Reporter.ReportEvent micFail, "Login", "User is unable to Login."

QTP - Recovery Scenarios

Recovery Scenarios

在执行 QTP 脚本时,我们可能会遇到一些意外错误。为了恢复测试并继续执行其余脚本,我们可使用以下意外错误进行恢复方案。可以通过导航到“资源”→恢复方案管理器进行访问恢复方案管理器,如下所示 −

qtp recovery scenario 1

Steps to Create Recovery Scenario

Step 1 − 单击“新建”恢复方案按钮;恢复方案向导将按如下所示打开 −

qtp recovery scenario 2

Step 2 − 选择触发器事件。它对应于可能在以下四种事件中发生的事件 −

  1. Pop-Up Window

  2. Object State

  3. Test Run Error

  4. Application Crash

Step 3 − 恢复操作窗口打开。恢复操作可以执行以下任何操作,如下面的屏幕截图所示 −

qtp recovery scenario 4

Step 4 − 指定适当的恢复操作后,我们还需要指定后恢复操作,如下所示 −

qtp recovery scenario 5

Step 5 − 指定后恢复操作后,应命名恢复方案并将其添加到测试中,以便激活它。

qtp recovery scenario 6

Step 6 − 恢复方案的创建已完成,需要通过选中“将方案添加到当前测试”选项并单击“完成”将其映射到当前测试。

qtp recovery scenario 7

Step 7 − 添加的恢复方案将如下所示,单击“关闭”按钮以继续。

qtp recovery scenario 8

Step 8 − 单击关闭按钮后,QTP 会提示用户保存创建的恢复方案。它将使用扩展名 .qrs 保存,向导将关闭。

qtp recovery scenario 9

Verification

创建的恢复方案现在应当成为测试的一部分,可以通过导航到“文件”→“设置”→“恢复”选项卡来验证此方案。

qtp recovery scenario 9

QTP - Environment Variables

QTP 环境变量是可由所有操作、函数库和恢复场景访问的特殊类型的变量。Windows 中有内置的环境变量,可供在该特定系统上运行的所有应用程序使用,但 QTP 环境变量在运行时仅可供该特定测试脚本使用。

Types of Environment Variables

Built-in Environment Variables −提供一系列环境参数,这些参数可提供诸如测试名称、操作名称、测试路径、本地主机名、操作系统名称、类型及其版本之类的信息。可以通过导航到“文件”→“测试设置”→“环境”选项卡来访问环境变量名称。

qtp environment 1

User defined Internal − 在“环境”选项卡窗口中选择“用户定义”可以保存用户定义变量。单击“+”按钮可输入“Parameter Name”(参数名称)和“Value”(值),如下所示:

qtp environment 2

User Defined External − 用户定义变量可以作为一个 .xml 文件存储在外部文件中,并且可以加载到测试中,如下面的图片所示。在运行时,它也可以动态地加载,如在下面的示例之一中所解释的。

qtp environment 3

Environment Variables – Supported Methods

1. ExternalFileName Property − 返回“测试设置”对话框“环境”选项卡中指定的已加载外部环境变量文件的名称。如果没有加载外部环境变量文件,此属性将返回一个空字符串。

x = Environment.ExternalFileName
print x
qtp environment 4

2. LoadFromFile Method − 在运行时动态加载指定的(.xml)环境变量文件。使用此方法时,无需手动将环境变量添加到“环境”选项卡中。

Environment.LoadFromFile "D:\config.xml"
b = Environment.Value("Browser")
print b
qtp environment 5

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 environment 6

QTP - Library Files

为了将脚本模块化,已将库文件添加到 QTP 脚本中。它包括变量声明、函数、类等。它们实现了可重用,可在测试脚本之间共享。它们通过扩展名 .vbs 或 .qfl 保存。

可以通过导航至“文件”>>“函数库”来创建一个新的库文件。

Associating Function Libraries

@{}− 通过使用“文件”>“设置”>“资源”>“关联函数库”选项。单击“+”按钮以添加函数库文件并使用实际路径或相对路径添加它,如以下所示 −

qtp library 1

@{}− 使用 ExecuteFile 方法。

'Syntax : ExecuteFile(Filepath)
ExecuteFile "C:\lib1.vbs"
ExecuteFile "C:\lib2.vbs"

@{}− 使用 LoadFunctionLibrary 方法。

'Syntax : LoadFunctionLibrary(Filepath)
LoadFunctionLibrary "C:\lib1.vbs"
LoadFunctionLibrary "C:\lib2.vbs"

Method 4 − 自动化对象模型(AOM) - 这是一个用于控制 QTP 外部各种 QTP 操作的机制。通过 AOM,我们可以启动 QTP,打开测试,关联函数库等。应使用扩展名 .vbs 保存以下 VbScript,并在执行它时,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 - Automated Testing Results

Test Results

测试结果窗口为我们提供了足够的信息来显示传递、失败等步骤。测试执行后,结果窗口会自动打开(根据默认设置)。显示以下信息:

  1. Steps Passed

  2. Steps Failed

  3. Environment Parameters

  4. Graphical Statistics

qtp test results 1

Operations performed in Test Results

Converting Results to HTML

在结果查看器窗口中,导航到“文件”→“导出到文件”。导出运行结果对话框打开,如下所示:

qtp test results 2

我们可以选择要导出的报告类型。它可以是简要结果、详细结果,甚至可以选择节点。选择文件名并导出后,文件将保存为 .HTML 文件

Filtering the Results

可以根据状态、节点类型和迭代次数筛选结果。可以通过“测试结果窗口”中的“筛选器”按钮进行访问。

qtp test results 3

Raising Defects

可以通过访问“工具”→“添加缺陷”直接从测试结果窗口窗格将缺陷记录到 QC,该窗格会打开与 ALM 的连接,如下所示:

qtp test results 4

Test Results

可以在“工具”→“选项”→“运行会话”选项卡下配置自动测试结果窗口。如果需要,我们可以将其关闭,还可以打开“会话结束时自动导出结果”。

qtp test results 5

可以根据设置录制屏幕截图或影片。可以在“工具”→“选项”→“屏幕捕获”选项卡下配置相同内容。我们可以根据以下三个条件保存屏幕截图或影片:

  1. For Errors

  2. Always

  3. For Errors and Warnings

qtp test results 6

QTP - Working with GUI Objects

在脚本执行期间,QTP 将与多个 GUI 对象交互。因此,了解使用它能让我们有效地处理它的基本方法很重要。

Working with Text Box

以下是我们在运行时访问文本框的方法 -

  1. Set - 帮助测试人员在文本框中设置值

  2. Click - 单击文本框

  3. SetSecure - 用来安全地设置密码框中的文本

  4. WaitProperty - 等待属性值变为真

  5. Exist - 检查文本框是否存在

  6. GetROProperty("text") - 获取文本框的值

  7. GetROProperty("Visible") - 如果可见,则返回布尔值

Example

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

Working with Check Box

以下是可以用复选框工作的一些关键方法 -

  1. Set - 帮助测试人员设置复选框值“开”或“关”

  2. Click - 单击复选框。即使勾选或取消勾选,用户也不确定状态

  3. WaitProperty - 等待属性值变为真

  4. Exist − 检查复选框的存在

  5. GetROProperty("name") − 获取复选框的名称

  6. GetROProperty("Visible") - 如果可见,则返回布尔值

Example

'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

Working with Radio Button

以下是一些关键方法,使用这些方法可以操作单选按钮——

  1. Select(RadioButtonName) − 帮助测试人员将单选框设为“启用”

  2. Click − 单击单选按钮。即使单选按钮已启用或已禁用,测试人员也无法获取状态

  3. WaitProperty - 等待属性值变为真

  4. Exist − 检查单选按钮的存在

  5. GetROProperty("name") − 获取单选按钮的名称

  6. GetROProperty("Visible") - 如果可见,则返回布尔值

Example

'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

Working with Combo Box

以下是一些关键方法,使用这些方法可以操作组合框——

  1. Select(Value) − 帮助测试人员从组合框中选择值

  2. Click − 单击对象

  3. WaitProperty - 等待属性值变为真

  4. Exist − 检查组合框的存在

  5. GetROProperty("Text") − 获取组合框中的已选择值

  6. GetROProperty("all items") − 返回组合框中的所有项目

  7. GetROProperty("items count") − 返回组合框中的项目数

Example

'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

Working with Buttons

以下是一些关键方法,使用这些方法可以操作按钮——

  1. Click − 单击按钮

  2. WaitProperty - 等待属性值变为真

  3. Exist − 检查按钮是否存在

  4. GetROProperty("Name") − 获取按钮的名称

  5. GetROProperty("Disabled") − 如果启用/禁用,则返回布尔值

Example

'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

Working with webTables

在当今基于 Web 的应用程序中,Web 表格已变得非常普遍,测试人员需要了解 Web 表格的工作原理以及如何对 Web 表格执行操作。本主题将帮助您高效地使用 Web 表格。

Sr.No.

Statement & Description

1

if statement An if 语句由一个布尔表达式以及一个或多个语句组成。

2

if…​else statement An if else 语句由一个布尔表达式以及一个或多个语句组成。如果条件为真, if 语句中的语句将被执行。如果条件为假,则脚本的 Else 部分将被执行。

3

if..elseif…​else statement An if 语句后跟一个或多个 Elseif 语句,这些语句由布尔表达式组成,然后是可选的 else statement ,当所有条件都为假时,该可选语句将执行。

4

nested if statements An if 或 elseif 语句位于另一个 ifelseif 语句内。

5

switch statement A switch 语句允许对变量进行测试,以与值列表保持相等。

  1. html id − 如果表格有一个 id 标记,则最好利用这个属性。

  2. innerText − 表格的标题。

  3. sourceIndex − 获取表格的源索引。

  4. ChildItemCount − 获取指定行中存在的子项的数目。

  5. RowCount − 获取表格中的行数。

  6. ColumnCount − 获取表格中的列数。

  7. GetcellData − 根据列和行索引获取单元格的值。

Example

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 - Virtual Objects

What are Virtual Objects?

有时,被测应用程序可能包含标准窗口对象,但未被 QTP 识别。在这种情况下,对象可以定义为按钮、链接等类型的虚拟对象 (VO),以便在执行期间可以在虚拟对象上模拟用户操作。

Example

假设我们在 Microsoft Word 中自动化场景。我激活了 MS Word 应用程序,并单击功能区中的任何图标。例如,在功能区中单击“插入”选项卡,然后单击“图片”按钮。按钮被识别为 WinObject;因此,虚拟对象的重要性变得明显。

Window("Microsoft Word").WinObject("Ribbon").Click 145,45
Window("Microsoft Word").WinObject("Ribbon").WinObject("Picture...").Click
170,104

Creating a Virtual Object

Step 1 − 在这种情况下,使用虚拟对象管理器或“工具”>>“虚拟对象”>>“新建虚拟对象”中的新建虚拟对象创建虚拟对象,然后单击“下一步”按钮。

qtp virtual objects 1

Step 2 − 将对象与类类型映射,然后单击“下一步”。

qtp virtual objects 2

Step 3 − 单击“标记对象”按钮。将出现十字光标,标记您要映射的对象,然后单击“下一步”。

qtp virtual objects 3

Step 4 − 选择虚拟对象的父级,然后单击“下一步”。

qtp virtual objects 4

Step 5 − 命名要存储虚拟对象的集合,然后单击“完成”。

qtp virtual objects 5

Virtual Object Manager

虚拟对象管理器管理虚拟对象的集合。测试人员可以从虚拟对象管理器中添加或删除虚拟对象。

导航到虚拟对象管理器:“工具”>>“虚拟对象管理器”,如下所示 −

qtp virtual objects 6

Using Virtual Objects

创建虚拟对象后,可以使用创建的对象,如下所示 −

Window("Microsoft Word").WinObject("Ribbon").VirtualButton("button").Click

Virtual Object Limitations

  1. QTP 不支持用于模拟或低级别记录的虚拟对象。

  2. 不能在虚拟对象上添加检查点。

  3. 对象仓库不控制虚拟对象。

  4. 尽管我们将对象映射到特定类别(按钮或列表),但虚拟对象不支持所有本机对象的函数。

  5. 虚拟对象无法使用对象侦察。

  6. 如果屏幕分辨率更改,测试执行将失败,因为坐标会发生变化。

  7. 应用程序窗口应采用相同的屏幕大小,以便正确捕获虚拟对象。

QTP - Accessing Databases

QTP 本身不提供连接到数据库的任何内置支持,但使用 VBScript 测试人员将能够使用 ADODB 对象连接到数据库并与之交互。

ADODB 有 4 个属性或方法,我们可以用它们来处理数据库。它们是:

  1. ADODB.Connection - 用于建立与数据库的连接

  2. ADODB.Command - 用于执行 SQL 命令(查询或存储过程)

  3. ADODB.Fields - 用于在执行查询/存储过程后从记录集中提取特定列

  4. ADODB.Recordset - 用于从数据库中提取数据

How to connect to Database?

数据库可以使用连接字符串进行连接。连接到各个数据库的方式有所不同。但是,可以在 www.connectionstrings.com 的帮助下构建连接字符串

让我们看看如何使用以下参数连接到数据库−

  1. Database Type − MSSQL SERVER

  2. Server Name − SQLEXPRESS

  3. Database Name − Trial

  4. User Id − sa

  5. password − Password123

查询的输出显示在 SQL Server Management Studio 中,如下所示:

qtp accessing db1
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

Result

执行上述脚本后,输出显示在消息框中,如下所示:

qtp accessing db2

QTP Working with XML

XML 是一种标记语言,设计用于将数据存储为人类和机器都可以读取的格式。使用 XML 还可以轻松地在计算机和数据库系统之间交换数据。

示例 XML 及其关键元素如下所示 −

qtp xml 1

Accessing 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

Comparing 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 - Descriptive Programming

当对象存在于对象存储库中时,QTP 脚本才能执行。对象描述使用说明性编程创建:

  1. 当测试人员想要对对象存储库中没有的对象执行操作时

  2. 当应用程序中的对象本质上非常动态时

  3. 当对象存储库变大时,它会导致性能下降,因为对象存储库的大小会增加

  4. 构建框架时,决定根本不使用对象存储库

  5. 测试员在运行时希望执行应用程序上的动作,但不了解对象的唯一属性。

Syntax

使用描述性编程技术编写脚本有两种方法。它们是 -

  1. Description Objects

  2. Description Strings

Description Objects

脚本使用依赖于所用属性及其相应值的对象描述来开发。然后,这些描述用于构建脚本。

'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

Description Strings

对象的描述使用属性和值(如字符串)来开发,如下所示。

Browser("Math Calc").Page("Num Calculator").WebButton("html
tag:=INPUT","type:=Button","name:=calculate").Click

Child Objects

QTP 提供 ChildObjects 方法,它使我们能够创建对象集合。父对象位于 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

Ordinal Identifiers

描述性编程用于基于序数标识符编写脚本,当两个或多个对象具有相同属性时,这将使 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 - Automation Object Model

QTP 本身可以使用由惠普 QTP 提供的 COM 接口进行自动化。自动化对象模型是一组对象、方法和属性,可帮助测试人员控制配置设置并使用 QTP 界面执行脚本。列出可以控制的关键配置/操作(但不限于):

  1. 加载测试所需的所有加载项

  2. 在执行期间使 QTP 可见

  3. 使用指定位置打开测试

  4. Associates Function Libraries

  5. 指定通用对象同步超时

  6. Start and End Iteration

  7. Enable/Disable Smart Identification

  8. On Error Settings

  9. Data Table Path

  10. Recovery Scenario Settings

  11. Log Tracking Settings

QTP 11.5x 提供了自动化对象模型的独家文档,可通过导航到“开始”>>“所有程序”>>“惠普软件”>>“惠普统一功能测试”>>“文档”>>“统一功能测试自动化参考”来引用。

Generate AOM Script

测试人员可以使用“生成脚本”选项从 QTP 本身生成 AOM 脚本。导航到“运行”>>“设置”>>“属性”选项卡 >>“生成脚本”,如下所示:

qtp aom 1

Example

' 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 - Frameworks

框架定义了一套准则/最佳实践来执行一组标准,这让最终用户易于使用。有不同类型的自动化框架,最常见的类型如下:

  1. Keyword-Driven Framework

  2. Data-Driven Framework

  3. Hybrid Framework

Keyword-Driven Framework

关键字驱动测试是一种类型的功能自动测试框架,也称为表格驱动测试或动作词驱动测试。

在关键字驱动测试中,我们使用表格格式(通常是电子表格)来针对我们要执行的每个功能定义关键词或动作词。

qtp keyword driven testing

Advantages

  1. 它最适合新手或非技术测试人员。

  2. 能够使用此方法以更抽象的方式编写测试。

  3. 关键字驱动测试允许在 SDLC 中更早地开始自动化,甚至早于交付稳定的构建进行测试。

  4. 它有很高的可重用性。

Disadvantages

  1. 最初投入开发关键词及其相关功能可能需要更长时间。

  2. 它可能会对有技术能力的测试人员构成限制。

Data Driven Framework

数据驱动测试是创建测试脚本的地方,其中每次运行测试时,测试数据和/或输出值从数据文件读取,而不是使用相同的硬编码值。通过这种方式,测试人员可以有效地测试应用程序如何处理各种输入。它可以是以下任何数据文件:

  1. datapools

  2. Excel files

  3. ADO objects

  4. CSV files

  5. ODBC sources

Flow Diagram

数据驱动测试可以通过以下图表得到最好的理解:

qtp data driven testing

Advantages

  1. 数据驱动框架导致的代码量更少

  2. 为维护和修复脚本问题提供了更大的灵活性

  3. 可以开发测试数据

Disadvantages

  1. 不同的脚本用于理解不同的数据。

Hybrid Framework

混合框架是关键字驱动和数据驱动框架的结合,下图是对它的最佳描述。

qtp hybrid framework

Affecting Factors

以下是开发框架时应该考虑的参数。影响因素如下所示 -

  1. 框架文件应该支持版本控制软件,例如 SVN、CVS、MS 源代码控制

  2. 框架应该支持在不同的环境中执行脚本,例如 QA、SAT 和 DEV

  3. 在对象发生更改后,脚本应该执行必要的最小更改。

  4. 框架应该进行自我配置,并处理前提条件,例如创建文件夹/数据库。

  5. 框架应该具有健壮的报告结构,以便于轻松发现脚本/应用程序中的问题。

  6. 框架应该具有更大的灵活性,以便于使用

  7. 框架应该遵循编码标准,以便正确维护文件、功能和更改历史记录。

在下一章,我们将学习如何设计一个简单的框架。

QTP - Designing Framework

让我们通过一个示例应用程序来设计一个简单的框架。我们将在受测应用程序中自动执行几个场景并编写可重用函数。

受测示例应用程序为 "Calculator" ,它是作为 Windows 一部分可用的一款默认应用程序。现在让我们创建框架的不同组件。在这里,我们将开发一个混合框架,并使用对象存储库,因为它是一个相当简单的应用程序。但是,该框架也可以扩展以支持复杂应用程序。

框架的文件夹结构如下所示:

qtp framework folder structure

文件夹结构的说明 −

  1. Master Driver Script − 驱动整个执行的脚本。它执行执行所需的先决条件和初始设置。

  2. Library Files − 形成函数库的相关函数。

  3. Data Table − 执行所需的测试数据。

  4. Object Repository − 允许 QTP 无缝识别对象的这些对象及其属性。

  5. Execution Logs − 文件夹包含带有用户函数和函数执行历史记录的执行日志文件。

Master Driver Script

'= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
' 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 =====================

Library Files

计算器函数是用单独的函数文件编写的,该文件使用扩展名 .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 添加到存储库的所有对象的列表。

qtp object repository calc

Data Table

数据表包含关键词,它驱动测试,并测试数据,QTP 将使用这些数据对对象进行操作。

qtp designing framework datatable

The Execution Log

执行日志文件或输出文件包含用户操作和函数日志,将使测试员能够在脚本故障时进行调试。

qtp designing framework execution log
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: ## # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # #