<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Real projects examples for you to learn Automated Testing_QTP, Selenium, TestPartner, RFT, XML</title>
	<atom:link href="http://automation.youplayoff.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://automation.youplayoff.com</link>
	<description></description>
	<lastBuildDate>Tue, 20 Dec 2011 01:44:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>#32: Tips for XML scripts</title>
		<link>http://automation.youplayoff.com/2011/09/03/32/</link>
		<comments>http://automation.youplayoff.com/2011/09/03/32/#comments</comments>
		<pubDate>Sat, 03 Sep 2011 15:56:20 +0000</pubDate>
		<dc:creator>Jia Qi</dc:creator>
				<category><![CDATA[Extensible Markup Language (XML)]]></category>
		<category><![CDATA[Compare double data]]></category>
		<category><![CDATA[Compare float data]]></category>
		<category><![CDATA[Data Type]]></category>
		<category><![CDATA[double]]></category>
		<category><![CDATA[float]]></category>
		<category><![CDATA[integer]]></category>
		<category><![CDATA[ulong]]></category>
		<category><![CDATA[Variable scope]]></category>

		<guid isPermaLink="false">http://automation.youplayoff.com/?p=513</guid>
		<description><![CDATA[Our customized XML scripts (see post#31) is based on C++, so C++ rules apply. I will discuss some common mistakes here: Variable scope: The following script is wrong. &#8220;$checkori&#8221; will return Null since &#8220;script:$path&#8221; is Null. The reason is the scope of &#8220;$path&#8221; is limited inside the If statements. The correct way of the above [...]]]></description>
			<content:encoded><![CDATA[<p>Our customized XML scripts (see <a href="http://automation.youplayoff.com/2011/08/27/31/">post#31</a>) is based on C++, so C++ rules apply. I will discuss some common mistakes here:</p>
<p><strong>Variable scope:</strong></p>
<p>The following script is wrong. &#8220;$checkori&#8221; will return Null since &#8220;script:$path&#8221; is Null. The reason is the scope of &#8220;$path&#8221; is limited inside the If statements.</p>
<pre class="brush:xml">
		<if test="or(equal($mode, 'B-Mode'), equal($mode, 'Adv-Contrast-Mode'))">
			<!-- $path: Acq/$mode/Scan/Line-Density -->
			<action code="=($path, 'Acq/')"/>
			<action code="+=($path, $mode)"/>
			<action code="+=($path, '/Scan/Line-Density')"/>
		</if>
		<if test="equal($mode, 'Contrast-Mode')">
			<!-- $path: Acq/B-Mode/Scan/Line-Density -->
			<action code="+=($path, 'Acq/B-Mode/Scan/Line-Density')"/>
		</if>

		<!-- read current Line Density value -->
<pdm action="read" name="script:$path" return="$checkori"/>
</pre>
<p>The correct way of the above script is as below: set initialize value to &#8220;$path&#8221; outside the If statements.</p>
<pre class="brush:xml">
		<action code="=($path, 'Acq/')"/>
		<if test="or(equal($mode, 'B-Mode'), equal($mode, 'Adv-Contrast-Mode'))">
			<!-- $path: Acq/$mode/Scan/Line-Density -->
			<action code="+=($path, $mode)"/>
			<action code="+=($path, '/Scan/Line-Density')"/>
		</if>
		<if test="equal($mode, 'Contrast-Mode')">
			<!-- $path: Acq/B-Mode/Scan/Line-Density -->
			<action code="+=($path, 'B-Mode/Scan/Line-Density')"/>
		</if>

		<!-- read current Line Density value -->
<pdm action="read" name="script:$path" return="$checkori"/>
</pre>
<p><strong>Data Type:</strong></p>
<p>The following script is wrong. An error will pop up when running the script since the original data type of &#8220;$check&#8221; is integer(ulong). Integer parameter can not multiply float(double) 40.3696.</p>
<pre class="brush:xml">
			<!-- Decode Voltage $V= $check * 40.2696 / 255 -->
			<action code="=($check, multiply($check, 40.2696))"/>
			<action code="=($V, divide($check, 255))"/>
</pre>
<p>The correct way of the above script is as below: change the data type of &#8220;$check&#8221; to double before the multiply.</p>
<pre class="brush:xml">
			<!-- Decode Voltage $V= $check * 40.2696 / 255.0 -->
			<action code="changetype($check, 'double')"/>
			<action code="=($check, multiply($check, 40.2696))"/>
			<action code="=($V, divide($check, 255.0))"/>
</pre>
<p><strong>Compare float(double) data:</strong></p>
<p>The following script can go wrong since both &#8220;$target&#8221; and &#8220;$check&#8221; are float(double) data. Say we set &#8220;$target&#8221; to 0.5, then we may expect &#8220;$target&#8221;=&#8221;$check&#8221; since the display value of &#8220;$check&#8221; is 0.5, but actually they are not equal since the real value of &#8220;$check&#8221; is 0.50000000000002.</p>
<pre class="brush:xml">
		<if test="equal($target, $check)">
			<action code="=($flag, 'PASS break')"/>
			<action code="=($logmsg, 'PASS! Current Image Width is ')"/>
			<action code="+=($logmsg, $check)"/>
			<action code="+=($logmsg, 'mm as expected.')"/>
			<log>script:$logmsg</log>
		</if>
</pre>
<p>The correct way of the above script is as below: compare the difference between &#8220;$target&#8221; and &#8220;$check&#8221; with a very small decimal number, such as 0.0001.</p>
<pre class="brush:xml">
		<action code="=($diff, subtract($target, $check))"/>
		<action code="=($diff, abs($diff))"/>
		<if test="less($diff, 0.0001)">		<!-- if $target = $check -->
			<action code="=($flag, 'PASS break')"/>
			<action code="=($logmsg, 'PASS! Current Image Width is ')"/>
			<action code="+=($logmsg, $check)"/>
			<action code="+=($logmsg, 'mm as expected.')"/>
			<log>script:$logmsg</log>
		</if>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://automation.youplayoff.com/2011/09/03/32/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>#31: Use embedded XML scripts to automate Ultrasound Machine tests</title>
		<link>http://automation.youplayoff.com/2011/08/27/31/</link>
		<comments>http://automation.youplayoff.com/2011/08/27/31/#comments</comments>
		<pubDate>Sat, 27 Aug 2011 22:51:36 +0000</pubDate>
		<dc:creator>Jia Qi</dc:creator>
				<category><![CDATA[Extensible Markup Language (XML)]]></category>
		<category><![CDATA[abs]]></category>
		<category><![CDATA[action statement]]></category>
		<category><![CDATA[add]]></category>
		<category><![CDATA[assign]]></category>
		<category><![CDATA[automated scripts]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[change type]]></category>
		<category><![CDATA[component specific script elements]]></category>
		<category><![CDATA[condition statement]]></category>
		<category><![CDATA[divide]]></category>
		<category><![CDATA[Embedded]]></category>
		<category><![CDATA[Engineering mode]]></category>
		<category><![CDATA[file statement]]></category>
		<category><![CDATA[function statement]]></category>
		<category><![CDATA[get type]]></category>
		<category><![CDATA[keyboard input]]></category>
		<category><![CDATA[link statement]]></category>
		<category><![CDATA[log statement]]></category>
		<category><![CDATA[loop statement]]></category>
		<category><![CDATA[Medical Systems]]></category>
		<category><![CDATA[multiply]]></category>
		<category><![CDATA[parameter value]]></category>
		<category><![CDATA[read from hardware]]></category>
		<category><![CDATA[read from software]]></category>
		<category><![CDATA[Real-Time]]></category>
		<category><![CDATA[script block]]></category>
		<category><![CDATA[set length]]></category>
		<category><![CDATA[sleep statement]]></category>
		<category><![CDATA[subtract]]></category>
		<category><![CDATA[Ultrasound Machine]]></category>
		<category><![CDATA[user interface input]]></category>
		<category><![CDATA[variable and array]]></category>
		<category><![CDATA[write from hardware]]></category>
		<category><![CDATA[write from software]]></category>

		<guid isPermaLink="false">http://automation.youplayoff.com/?p=470</guid>
		<description><![CDATA[I have disappeared for 8 months&#8230; Even though there was no new posts in these months, but I did get a lot done: First, the measurement and export tests in workstation are fully automated by TestPartner using VBA scripts, which saved 1 tester 18 testing days. (I won&#8217;t create any new posts for TestPartner, since [...]]]></description>
			<content:encoded><![CDATA[<p>I have disappeared for 8 months&#8230; Even though there was no new posts in these months, but I did get a lot done:</p>
<p>First, the measurement and export tests in workstation are fully automated by TestPartner using VBA scripts, which saved 1 tester 18 testing days. (I won&#8217;t create any new posts for TestPartner, since if you fully understand <a href="http://automation.youplayoff.com/category/testpartner-tp/">the existing 20 posts of TestPartner</a>, you should be able to solve any problem in TestPartner.)</p>
<p>Second, starting from June, in 3 months time, I finished writing XML scripts to automate the transducer tests for our Ultrasound Machines, which saved 1 tester 12 testing days. Use embedded XML scripts to automate Ultrasound Machine tests is a huge step for us, since this represents that we are not only able to automate pure software tests (workstation tests), we now able to automate Real-Time system tests which has its own hardware! For more discussions about how big this step is, please refer to <a href="http://automation.youplayoff.com/2010/07/20/15/">post#15: Automated Testing for Real-Time Embedded Medical Systems</a>.</p>
<p>Now let&#8217;s talk about how to use the embedded XML scripts to automate Ultrasound Machine tests:<br />
<a href="http://automation.youplayoff.com/wp-content/uploads/2011/08/Ultrasound-Machine.jpg"><img src="http://automation.youplayoff.com/wp-content/uploads/2011/08/Ultrasound-Machine-171x300.jpg" alt="" title="Ultrasound Machine" width="171" height="300" class="alignright size-medium wp-image-486" /></a><br />
The Ultrasound Systems developed by my company is just like those Ultrasound machines you see in hospitals. It contains a monitor, a custom designed keyboard, and a card cage. Inside the card cage, there are a normal computer and our custom designed hardware – multiple electronic boards. FPGA is on one of the board, which does all the calculation. Also, the system is connected to a transducer, which send and receive ultrasound signals.</p>
<p>In order to automate the Ultrasound Machine tests, we need to use scripts to simulate keyboard/user interface input, and read/write software/hardware parameter values. These become possible by using the embedded background Engineering mode of our Ultrasound application. The Ultrasound application is visible to customers, i.e., machine operators can see the ultrasound images and parameter values on the monitor, and able to use the keyboard to control these values in order to modify the ultrasound images. On the contrary, the Engineering mode is invisible to customers, but visible to developers and testers. All the software and hardware parameter values are actually controlled in Engineering mode. These values on the Ultrasound application are just an output of the Engineering mode values.</p>
<p>The Engineering mode was not originally designed for automation tests, it was needed by developers to support the Ultrasound application anyways. The Engineering mode is the internal core of the Ultrasound software, the customer visible Ultrasound application is just the outside shell. To interpret XML scripts is one of the functions of the Engineering mode. This scripting function was originally there since developers needed it to do their own tests. Now, what I need to do is just by adopting the script function in Engineering mode to do the automation tests of the Ultrasound Machines.</p>
<p>Extensible Markup Language (XML) is a set of rules for encoding documents in machine-readable form. All XML scripts are customized to make it your machine-readable. In my company, the Ultrasound software is coded by C++, so our XML script is customized in C++ by our developers. They also created a 30 pages long software design description to provide the software design and usage description for our customized XML scripting language, including script block, variable and array, log statement, action statement (assign, add, subtract, multiply, divide, abs, get type, change type, set length), sleep statement, loop statement, condition statement, link statement, function statement, file statement, and component specific script elements.</p>
<p>The component specific script elements section explaines how to simulate the keyboard/user interface input and read/write software/hardware parameter values: </p>
<p>Keyboard input:</p>
<pre class="brush:xml">
<!-- click [AppSelect] key and wait 1 sec -->
<cmd code="AppSelect"/>
<sleep time="1000"/>
</pre>
<p>User interface input:</p>
<pre class="brush:xml">
<ui>
<input key="script:$app"/>  <!-- select proper application and wait 1 sec-->
<input key="#SE"/>  <!-- use Enter key to OK the Select Application window -->
</ui>
</pre>
<p>Read from software (called as &#8220;pdm&#8221;) parameter values:</p>
<pre class="brush:xml">
<pdm action="read" name="App/Settings/System/State" return="$check"/>
</pre>
<p>Write from software (called as &#8220;pdm&#8221;) parameter values:</p>
<pre class="brush:xml">
<pdm action="write" name="App/Settings/Hardware/3D-Motor-State" base="10">3</pdm>
</pre>
<p>Read from hardware (called as &#8220;dcm&#8221;) parameter values:</p>
<pre class="brush:xml">
<dcm action="read" name="Hardware/Tx/HwTxCbCommon/VP-Mode1"/>
</pre>
<p>Write from hardware (called as &#8220;dcm&#8221;) parameter values:<br />
not in use</p>
]]></content:encoded>
			<wfw:commentRss>http://automation.youplayoff.com/2011/08/27/31/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>#30: Different Software Design Life Cycle (SDLC) Models</title>
		<link>http://automation.youplayoff.com/2010/12/11/30/</link>
		<comments>http://automation.youplayoff.com/2010/12/11/30/#comments</comments>
		<pubDate>Sun, 12 Dec 2010 00:09:16 +0000</pubDate>
		<dc:creator>Jia Qi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Agile Methodology]]></category>
		<category><![CDATA[Dynamic Systems Development Method (DSDM)]]></category>
		<category><![CDATA[Extreme Programming]]></category>
		<category><![CDATA[Incremental or Iterative Development Model]]></category>
		<category><![CDATA[Prototyping Model]]></category>
		<category><![CDATA[SCRUM]]></category>
		<category><![CDATA[Software Design Life Cycles (SDLC)]]></category>
		<category><![CDATA[test-driven development]]></category>
		<category><![CDATA[Waterfall Model]]></category>

		<guid isPermaLink="false">http://automation.youplayoff.com/?p=454</guid>
		<description><![CDATA[Software Design Life Cycles (SDLC) Models: - Waterfall Model - Incremental or Iterative Development Model - Prototyping Model - Agile Methodology (Agile methodology has various derivate approaches, such as Extreme Programming, Dynamic Systems Development Method (DSDM), and SCRUM. Extreme Programming is one of the most widely used approaches. Test-driven development is one of the core [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Software Design Life Cycles (SDLC) Models:</strong><br />
- <strong>Waterfall Model</strong><br />
- <strong>Incremental or Iterative Development Model</strong><br />
- <strong>Prototyping Model</strong><br />
- <strong>Agile Methodology</strong> (Agile methodology has various derivate approaches, such as <strong>Extreme Programming</strong>, <strong>Dynamic Systems Development Method (DSDM)</strong>, and <strong>SCRUM</strong>. Extreme Programming is one of the most widely used approaches. <strong>Test-driven development</strong> is one of the core practices of Extreme Programming. We talked about Test-driven development in <a href="http://automation.youplayoff.com/2010/10/02/21/">post#21</a>.)</p>
<p>For more information about above mentioned different software design life cycle models, please read <a href="http://msdn.microsoft.com/en-us/library/ff649520.aspx">here</a>.</p>
<p>The above article describes Extreme Programming in details, but doesn&#8217;t mention much about SCRUM. To understand how SCRUM works, please read &#8220;<a href="http://www.agile-software-development.com/2007/09/how-to-implement-scrum-in-10-easy-steps.html">How to implement Scrum in 10 easy steps</a>&#8220;.</p>
<p><strong>What are the differences between SCRUM and Extreme Programming?</strong><br />
   1. Scrum teams typically work in iterations (called sprints) that are from two weeks to one month long. XP teams typically work in iterations that are one or two weeks long.<br />
   2. Scrum teams do not allow changes into their sprints. A new feature of equivalent size can be swapped into the XP team’s iteration in exchange for the unstarted feature.<br />
   3. Extreme Programming teams work in a strict priority order. By contrast, the Scrum product owner prioritizes the product backlog but the team determines the sequence in which they will develop the backlog items.<br />
   4. Scrum doesn’t prescribe any engineering practices; XP does.</p>
<p>For more information about the differences between Scrum and Extreme Programming, please read <a href="http://blog.mountaingoatsoftware.com/differences-between-scrum-and-extreme-programming">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://automation.youplayoff.com/2010/12/11/30/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>#29: Selenium (Selenium-IDE, Selenium RC, Selenium Grid)</title>
		<link>http://automation.youplayoff.com/2010/12/05/29/</link>
		<comments>http://automation.youplayoff.com/2010/12/05/29/#comments</comments>
		<pubDate>Sun, 05 Dec 2010 18:11:24 +0000</pubDate>
		<dc:creator>Jia Qi</dc:creator>
				<category><![CDATA[Selenium]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[HP QTP]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Selenium Grid]]></category>
		<category><![CDATA[Selenium RC]]></category>
		<category><![CDATA[Selenium Remote Control]]></category>
		<category><![CDATA[Selenium Tutorial]]></category>
		<category><![CDATA[Selenium-IDE]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[WAMP]]></category>

		<guid isPermaLink="false">http://automation.youplayoff.com/?p=434</guid>
		<description><![CDATA[Most small/medium sized website companies use LAMP for their development, because it is free. LAMP is an acronym for a solution stack of free, open source software, originally coined from the first letters of Linux (operating system), Apache HTTP Server, MySQL (database software) and Perl/PHP/Python, principal components to build a viable general purpose web server. [...]]]></description>
			<content:encoded><![CDATA[<p>Most small/medium sized website companies use LAMP for their development, because it is free.</p>
<p>LAMP is an acronym for a solution stack of free, open source software, originally coined from the first letters of Linux (operating system), Apache HTTP Server, MySQL (database software) and Perl/PHP/Python, principal components to build a viable general purpose web server.</p>
<p>The testing team in these companies use Selenium, which is free, too.</p>
<p>Selenium is a portable software testing framework for web applications. Selenium provides a test domain specific language (DSL) to write tests in a number of popular programming languages, including C#, Java, Ruby, Groovy, Python, PHP, and Perl. In this blog, we will focus on Selenium IDE, which is a complete Integrated Development Environment (IDE) for Selenium tests. It is implemented as a Firefox extension, and allows recording, editing, and debugging tests.</p>
<p><a href="http://seleniumhq.org/docs/03_selenium_ide.html">How to install Selenium IDE</a>.<br />
<a href="http://seleniumhq.org/download/">Download Selenium IDE</a>.</p>
<p>Other bigger website companies use IIS instead of Aphache, SQL Server instead of MySQL, ASP.NET instead of PHP, HP QTP instead of Selenium. None of these are free.</p>
<p>I will show you some examples about how to use Selenium IDE in the future posts, and I will try to explore as many Selenium supported languages as possible.</p>
<p>======================================================<br />
Get started with Selenium:</p>
<p>Selenium is <a href="http://seleniumhq.org/projects/">a suite of tools</a> to automate web app testing across many platforms. The relationship among Selenium IDE, Selenium Remote Control and Selenium Grid is displayed in this <a href="http://seleniumhq.org/about/how.html"> &#8220;How Selenium Works&#8221;</a> image.</p>
<p>Selenium&#8230;</p>
<p>    * runs in many browsers and operating systems<br />
    * can be controlled by many programming languages and testing frameworks.</p>
<p>Selenium supported Browsers, Operating Systems, Programming Languages, and Testing Frameworks are listed in <a href="http://seleniumhq.org/about/platforms.html">&#8220;Platforms Supported by Selenium&#8221;</a>.</p>
<p>After understand the Selenium family, now you are ready to<br />
Read the <a href="http://www.cs.drexel.edu/~spiros/teaching/SE320/slides/selenium.pdf">17 pages unofficial Selenium Tutorial</a> to understand how Selenium IDE works,<br />
And<br />
Read <a href="http://www.codediesel.com/php/selenium-ide-tutorial-part-1/">&#8220;Selenium IDE Tutorial – Part 1&#8243;</a> for a detailed example about using Selenium IDE, and <a href="http://www.codediesel.com/php/selenium-ide-tutorial-part-2/">&#8220;Selenium IDE Tutorial – Part 2&#8243;</a> for continued example about trasfer the test to Selenium Remote Control (Selenium RC),<br />
Then<br />
Read <a href="http://jroller.com/selenium/">&#8220;Selenium Tutorial for Beginner/Tips for Experts&#8221;</a> for an in-depth understanding of Selenium IDE and Selenium RC,</p>
<p>The official Selenium Documentation is also a good reference:<br />
Read the <a href="http://seleniumhq.org/docs/">online official Selenium Documentation</a>,<br />
Or<br />
Download and Read the <a href="http://seleniumhq.org/docs/book/Selenium_Documentation.pdf">printable official Selenium Tutorial (in pdf, 164pages)</a>,<br />
If the pdf can not be downloaded from the above website, you can download it from <a href="http://oss.infoscience.co.jp/seleniumhq/docs/book/Selenium_Documentation.pdf">here</a>.</p>
<p>Other good examples can be found at:<br />
<a href="http://oshyn.com/_blog/Software_Development/post/Selenium-IDE-Automated-Testing/">Selenium IDE for Automated Testing</a> shows you how to use Selenium IDE, run a simple test case “GoogleSignUpErrors” and export it as a Java file. </p>
<p><a href="http://oshyn.com/_blog/Software_Development/post/Selenium-RC-Automated-Testing">Selenium RC for Automated Testing</a> is a guide to install Selenium Remote Control and run “GoogleSignUpErrors” as a Java program.</p>
<p><a href="http://oshyn.com/_blog/Software_Development/post/Selenium-Test-Suite/">How to create a test suite in Selenium?</a> shows you how to create a test suite in Selenium IDE and run the group of test cases using Selenium RC. </p>
<p><a href="http://oshyn.com/_blog/Software_Development/post/Selenium-Test-Suite-Ubuntu/">Selenium Test Suite on Ubuntu</a>: In case you have a Ubuntu server running Hudson (software for Continuous Integration), you may want to make a first attempt to run a Selenium test suite in command line before setting up a Hudson job that automatically runs the test suite.</p>
<p><a href="http://oshyn.com/_blog/Software_Development/post/Hudson-Selenium-Test-Suite/">Hudson and SeleniumTest Suite</a>: suppose you have Hudson(software for Continuous Integration) installed in your server and you want to create a job that executes a Selenium Test suite.</p>
]]></content:encoded>
			<wfw:commentRss>http://automation.youplayoff.com/2010/12/05/29/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>#28: How to pause or stop playback in TestPartner</title>
		<link>http://automation.youplayoff.com/2010/12/03/28/</link>
		<comments>http://automation.youplayoff.com/2010/12/03/28/#comments</comments>
		<pubDate>Fri, 03 Dec 2010 21:02:51 +0000</pubDate>
		<dc:creator>Jia Qi</dc:creator>
				<category><![CDATA[TestPartner (TP)]]></category>
		<category><![CDATA[Pause playback]]></category>
		<category><![CDATA[Stop playback]]></category>

		<guid isPermaLink="false">http://automation.youplayoff.com/?p=429</guid>
		<description><![CDATA[Stop playback: Alt+F12 Pause playback: Ctrl+Pause/Break]]></description>
			<content:encoded><![CDATA[<p>Stop playback: Alt+F12<br />
Pause playback: Ctrl+Pause/Break</p>
]]></content:encoded>
			<wfw:commentRss>http://automation.youplayoff.com/2010/12/03/28/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>#27: How to modify script in QTP debug mode</title>
		<link>http://automation.youplayoff.com/2010/11/25/27/</link>
		<comments>http://automation.youplayoff.com/2010/11/25/27/#comments</comments>
		<pubDate>Fri, 26 Nov 2010 01:52:02 +0000</pubDate>
		<dc:creator>Jia Qi</dc:creator>
				<category><![CDATA[Quick Test Professional (QTP)]]></category>
		<category><![CDATA[TestPartner (TP)]]></category>
		<category><![CDATA[Command Tab]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[Debug Viewer]]></category>
		<category><![CDATA[modify script]]></category>
		<category><![CDATA[read only]]></category>
		<category><![CDATA[Variables Tab]]></category>
		<category><![CDATA[Watch Tab]]></category>

		<guid isPermaLink="false">http://automation.youplayoff.com/?p=422</guid>
		<description><![CDATA[The only thing that I do not like in QTP is scripts are read only in debug mode: if an error pop up during a playback in QTP, and I choose to &#8220;Debug&#8221;, then I can not modify anything since the script is read only. However, TestPartner is much more convenient in this particular area, [...]]]></description>
			<content:encoded><![CDATA[<p>The only thing that I do not like in QTP is scripts are read only in debug mode: if an error pop up during a playback in QTP, and I choose to &#8220;Debug&#8221;, then I can not modify anything since the script is read only. </p>
<p>However, TestPartner is much more convenient in this particular area, since its scripts can be modified during debug mode: once you choose to debug, the playback is paused, and you can modify your script, and drag the current step indicator (i.e., the yellow arrow) to the line where you want the script to resume.</p>
<p>The only work around in QTP debug mode is to use the Command tab in the Debug Viewer:</p>
<p>Using the Debug Viewer<br />
You use the Debug Viewer pane to view, set, or modify the current value of objects or variables in your function library, when it stops at a breakpoint, or when a step fails and you select the Debug option. The Debug Viewer is useful for debugging operations (functions) in a business component, but is not intended for use with other types of component steps. </p>
<p><a href="http://automation.youplayoff.com/wp-content/uploads/2010/11/Debug-Viewer.jpg"><img src="http://automation.youplayoff.com/wp-content/uploads/2010/11/Debug-Viewer-294x300.jpg" alt="" title="Debug Viewer" width="294" height="300" class="alignleft size-medium wp-image-423" /></a></p>
<p>To open the Debug Viewer pane: </p>
<p>Choose View > Debug Viewer. The Debug Viewer pane opens. </p>
<p>The Debug Viewer tabs are used to display the values of variables and objects in the main script of the selected subroutine. </p>
<p>Command Tab<br />
Use the Command tab to execute a line of script in order to set or modify the current value of a variable or VBScript object in your function library. When the run continues, QuickTest uses the value that you set. </p>
<p>A detailed example about how to use the Debug Viewer and its Watch Tab, Variables Tab, and Command Tab can be viewed from <a href="http://qtp.blogspot.com/2008/09/qtp-debug-viewer-pane.html">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://automation.youplayoff.com/2010/11/25/27/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>#26: Error handling in VBScript (QTP)</title>
		<link>http://automation.youplayoff.com/2010/11/24/26-error-handling-in-vbscript-qtp/</link>
		<comments>http://automation.youplayoff.com/2010/11/24/26-error-handling-in-vbscript-qtp/#comments</comments>
		<pubDate>Thu, 25 Nov 2010 03:54:35 +0000</pubDate>
		<dc:creator>Jia Qi</dc:creator>
				<category><![CDATA[Quick Test Professional (QTP)]]></category>
		<category><![CDATA[Error handling]]></category>
		<category><![CDATA[On Error GoTo]]></category>
		<category><![CDATA[On Error GoTo 0]]></category>
		<category><![CDATA[On Error Resume Next]]></category>
		<category><![CDATA[subroutine]]></category>
		<category><![CDATA[VBScript]]></category>

		<guid isPermaLink="false">http://automation.youplayoff.com/?p=414</guid>
		<description><![CDATA[In post#13 and post#23, we talked about how to do error handling in Visual Basic of Application (VBA), which is the scripting language for TestPartner. In today&#8217;s post, we will discuss how to handle errors in VBScript, which is the scripting language for QTP. In VBA, there are 3 error handling statements (for the meaning [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://automation.youplayoff.com/2010/07/01/13-error-handling-in-vba-testpartner/">post#13</a> and <a href="http://automation.youplayoff.com/2010/11/01/23/">post#23</a>, we talked about how to do error handling in Visual Basic of Application (VBA), which is the scripting language for TestPartner. In today&#8217;s post, we will discuss how to handle errors in VBScript, which is the scripting language for QTP.</p>
<p>In VBA, there are 3 error handling statements (for the meaning of these statements, please refer to <a href="http://automation.youplayoff.com/2010/07/01/13-error-handling-in-vba-testpartner/">post#13</a> or <a href="http://automation.youplayoff.com/2010/11/01/23/">post#23</a>.): </p>
<p><strong>1, On Error GoTo <em>line</em></strong><br />
This statement is <strong>NOT</strong> supported by VBScript, but you can use a <strong>subroutine</strong> to handle error output . See the script below.</p>
<pre class="brush:vb">
Const adOpenDynamic = 2
Const adLockOptimistic = 3
Const adCmdTableDirect = 512

Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
Set errorObject = CreateObject("ADODB.Error")

On Error Resume Next
cn.Provider = "sas.localprovider.1"
cn.Properties("Data Source") = "c:\testdata"

cn.Open
rs.Open "lostDataset", cn, adOpenDynamic, adLockOptimistic, adCmdTableDirect
DisplayErrorInfo
rs.Close
cn.Close

sub DisplayErrorInfo()
  For Each errorObject In rs.ActiveConnection.Errors
    MsgBox "Description: " &#038; errorObject.Description &#038; Chr(10) &#038; Chr(13) &#038; _
           "Number:      " &#038; Hex(errorObject.Number)
  Next
End Sub
</pre>
<p><strong>2, On Error Resume Next</strong><br />
This statement is supported by VBScript.</p>
<p><strong>3, On Error GoTo 0</strong><br />
This statement is supported by VBScript.</p>
<p>============================================</p>
<p>More reading material:<br />
<a href="http://blogs.msdn.com/b/ericlippert/archive/2004/08/19/error-handling-in-vbscript-part-one.aspx">Error Handling in VBScript, Part One</a><br />
<a href="http://blogs.msdn.com/b/ericlippert/archive/2004/08/23/218974.aspx">Error Handling In VBScript, Part Two</a><br />
<a href="http://blogs.msdn.com/b/ericlippert/archive/2004/08/25/error-handling-in-vbscript-part-three.aspx">Error Handling in VBScript, Part Three</a><br />
<a href="http://technet.microsoft.com/en-us/library/ee692852.aspx">To Err Is VBScript – Part 1</a><br />
<a href="http://technet.microsoft.com/en-us/library/ee692841.aspx">To Err Is VBScript – Part 2</a><br />
<a href="http://support.sas.com/documentation/tools/oledb/app_error_objects.htm">Handling Error Objects</a></p>
]]></content:encoded>
			<wfw:commentRss>http://automation.youplayoff.com/2010/11/24/26-error-handling-in-vbscript-qtp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>#25: Differences of Funtion that returns array in VBScript and VBA</title>
		<link>http://automation.youplayoff.com/2010/11/17/25/</link>
		<comments>http://automation.youplayoff.com/2010/11/17/25/#comments</comments>
		<pubDate>Thu, 18 Nov 2010 03:50:46 +0000</pubDate>
		<dc:creator>Jia Qi</dc:creator>
				<category><![CDATA[Quick Test Professional (QTP)]]></category>
		<category><![CDATA[TestPartner (TP)]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[Subscript out of range]]></category>
		<category><![CDATA[type mismatch]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[VBScript]]></category>

		<guid isPermaLink="false">http://automation.youplayoff.com/?p=397</guid>
		<description><![CDATA[To create and call a Function that returns array in VBScript and VBA are slightly different (QTP uses VBScript and TestPartner uses VBA): In VBA, Function GetExcelSheetData(FilePath As String, SheetName As String) Dim CellArray() As String 'A dynamic array that is not sized in the Dim statement ... Calculate RowCount and ColumnCount ReDim CellArray(RowCount, ColumnCount) [...]]]></description>
			<content:encoded><![CDATA[<p>To create and call a Function that returns array in VBScript and VBA are slightly different (QTP uses VBScript and TestPartner uses VBA):</p>
<p>In VBA,</p>
<pre class="brush:vb">
Function GetExcelSheetData(FilePath As String, SheetName As String)
Dim CellArray() As String 'A dynamic array that is not sized in the Dim statement
... Calculate RowCount and ColumnCount
ReDim CellArray(RowCount, ColumnCount) As String
... Populate data in CellArray
GetExcelSheetData = CellArray()
End Function
</pre>
<pre class="brush:vb">
Sub Main()
Dim SheetData() As String 'Dynamic array
.. Calculate RowCount and ColumnCount
ReDim SheetData(RowCount, ColumnCount) As String
SheetData() = Function_GetExcelSheetData.GetExcelSheetData(ExcelFilePath_MeasurementTab, "Package")
</pre>
<p>In VBScript,</p>
<pre class="brush:vb">
Function Function_ImportExcelToArray(FilePath, SheetName)
Dim CellArray 'A dynamic array that is not sized in the Dim statement
... Calculate RowCount and ColumnCount
ReDim CellArray(RowCount, ColumnCount)
... Populate data in CellArray
Function_ImportExcelToArray = CellArray
'Note: if write "Function_ImportExcelToArray = CellArray()",
'then will get error "Subscript out of range: 'CellArray'".
End Function
</pre>
<pre class="brush:vb">
Sub Sub_LoginRedirect()
Dim PageURL
'DO NOT write "PageURL()",
'otherwise, will get error "type mismatch".
.. Calculate RowCount and ColumnCount
ReDim PageURL(RowCount, ColumnCount)
PageURL = Function_ImportExcelToArray(InputExcel, "Sub_LoginRedirect")
'Note: if write "PageURL() = Function_ImportExcelToArray(InputExcel, "Sub_LoginRedirect")",
'then will get error "Subscript out of range: 'PageURL'".
</pre>
<p>Conclusion, in VBScript, do not use Array with empty brackets, such as Array(), but you can use not-empty brackets, such as Array(1, 2).</p>
<p>===========================================================</p>
<p><a href="http://msdn.microsoft.com/en-us/library/t7zd6etz%28VS.85%29.aspx">More information about Array in VBScript</a>:</p>
<p>Much of the time, you only want to assign a single value to a variable you have declared. A variable containing a single value is a scalar variable. Other times, it is convenient to assign more than one related value to a single variable. Then you can create a variable that can contain a series of values. This is called an array variable. Array variables and scalar variables are declared in the same way, except that the declaration of an array variable uses parentheses ( ) following the variable name. In the following example, a single-dimension array containing 11 elements is declared:</p>
<p><strong>Dim A(10)</strong></p>
<p>Although the number shown in the parentheses is 10, all arrays in VBScript are zero-based, so this array actually contains 11 elements. In a zero-based array, the number of array elements is always the number shown in parentheses plus one. This kind of array is called a fixed-size array.</p>
<p>You assign data to each of the elements of the array using an index into the array. Beginning at zero and ending at 10, data can be assigned to the elements of an array as follows:</p>
<p><strong>A(0) = 256<br />
A(1) = 324<br />
A(2) = 100<br />
 . . .<br />
A(10) = 55</strong></p>
<p>Similarly, the data can be retrieved from any element using an index into the particular array element you want. For example:</p>
<p><strong> . . .<br />
SomeVariable = A(8)<br />
 . . . </strong></p>
<p>Arrays aren&#8217;t limited to a single dimension. You can have as many as 60 dimensions, although most people can&#8217;t comprehend more than three or four dimensions. You can declare multiple dimensions by separating an array&#8217;s size numbers in the parentheses with commas. In the following example, the MyTable variable is a two-dimensional array consisting of 6 rows and 11 columns:</p>
<p><strong>Dim MyTable(5, 10)</strong></p>
<p>In a two-dimensional array, the first number is always the number of rows; the second number is the number of columns.</p>
<p>You can also declare an array whose size changes during the time your script is running. This is called a dynamic array. The array is initially declared within a procedure using either the Dim statement or using the ReDim statement. However, for a dynamic array, no size or number of dimensions is placed inside the parentheses. For example:<br />
<strong><br />
Dim MyArray()<br />
ReDim AnotherArray()</strong></p>
<p>To use a dynamic array, you must subsequently use ReDim to determine the number of dimensions and the size of each dimension. In the following example, ReDim sets the initial size of the dynamic array to 25. A subsequent ReDim statement resizes the array to 30, but uses the Preserve keyword to preserve the contents of the array as the resizing takes place.</p>
<p><strong>ReDim MyArray(25)<br />
 . . .<br />
ReDim Preserve MyArray(30)</strong></p>
<p>There is no limit to the number of times you can resize a dynamic array, although if you make an array smaller, you lose the data in the eliminated elements. </p>
]]></content:encoded>
			<wfw:commentRss>http://automation.youplayoff.com/2010/11/17/25/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>#24: How to run multiple TestPartner projects at once in Command Prompt</title>
		<link>http://automation.youplayoff.com/2010/11/11/24/</link>
		<comments>http://automation.youplayoff.com/2010/11/11/24/#comments</comments>
		<pubDate>Thu, 11 Nov 2010 15:43:19 +0000</pubDate>
		<dc:creator>Jia Qi</dc:creator>
				<category><![CDATA[TestPartner (TP)]]></category>
		<category><![CDATA[*.bat]]></category>
		<category><![CDATA[batch file]]></category>
		<category><![CDATA[cmd.exe]]></category>
		<category><![CDATA[Command Prompt]]></category>
		<category><![CDATA[run multiple projects at once]]></category>
		<category><![CDATA[tp.exe/?]]></category>

		<guid isPermaLink="false">http://automation.youplayoff.com/?p=386</guid>
		<description><![CDATA[There are mutiple people in my company are developing VBA scripts in TestPartner, and different people save their scripts under different projects, then a problem comes to us: How to run scripts from different projects at once? You can create a visual test in project A to play back all the test scripts and visual [...]]]></description>
			<content:encoded><![CDATA[<p>There are mutiple people in my company are developing VBA scripts in TestPartner, and different people save their scripts under different projects, then a problem comes to us: How to run scripts from different projects at once?</p>
<p>You can create a visual test in project A to play back all the test scripts and visual tests in project A and the common project, but this visual test can not play back any test scripts or visual tests from other projects, since Testpartner doesn&#8217;t give an option to do so.</p>
<p>So what you get are:<br />
visual test A to drive all the test scripts and visual tests from project A and common project which is related to project A;<br />
visual test B to drive all the test scripts and visual tests from project A and common project which is related to project B;<br />
visual test C to drive all the test scripts and visual tests from project A and common project which is related to project C;<br />
&#8230;</p>
<p>Since to execute visual test A may take hours to finish, people don&#8217;t want to wait until it is done then start to run visual test B. They want to run visual test ABC at once, problably overnight, then come in in the morning to check all the results.</p>
<p>How to do this:<br />
TestPartner provides us a solution by running scripts (either visual tests or test scripts) from multiple projects at once in the Command Prompt (executable name cmd.exe ), which you can find from Windows &#8211; Start &#8211; All programs &#8211; Accessories &#8211; Command Prompt</p>
<p>Once the DOS like black screen of Command Prompt is opened, you can type in &#8220;tp.exe/?&#8221; to see the help (you can only do this on a computer which has TestPartner installed).</p>
<pre class="brush:xml">
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\user>tp.exe/?

  TP.exe : Version 2.00
  (c)Compuware Corporation, 2002-2009  All Rights Reserved.

    Description :

        Starts TestPartner in automation mode

    Usage :

        TP.exe [parameters]

    Flags:

         Note that a flag starts with a "-" or a "/" character and can be a
         single character or a the full word, note that flags are handled case
         sensitive(DSN=dsn=DsN)

    Where parameters are ..

      -d  {dsn} .................The name of a the DSN to use to connect to the
                                  database.  Optional.  Uses "TestPartner" by
                                  default.

      -u  {username} ............ The name of the user used to connect.

      -p  {password} ............The password of the user used to connect
.
                                  Optional if password is Null.

      -r  {project} .............The project containing test script/visual test
                                  to be played back. Optional if test script
                                  /visual test is in the "Common" project.

      -s  {testscript} ..........The name(s) of test scripts to be played back.

      -t  {visualtest} ..........The name(s) of visual tests to be played back.

      -m  {vtvariable} ..........The name and value pair(s) for visual tests
                                  variable(s).
                                  Enclose the name and value pair(s) in double
                                  quotes.
                                  Use an 'equal to' character (=) to
                                  denote a value that's assigned to a variable.

      -a  {append} .............. Add the append parameter to append the
                                  result.  Optional.

      -i  {increment} ...........Add the increment parameter to increment the
                                  result.   Optional.

      -v  {verbose} .............Output additional useful text messages.

      -h or ?  {help} ...........Displays this message.

      Parameters that are required for flags can be specified a number of ways.

      1. As a separate value following the parameter, e.g.

         -d MyDsn -u admin -p adminpassword -s testscript1 testscript2

         If the parameter contains a space the value should be placed in double
         quotes, e.g.

         -d MyDsn -u admin -p adminpassword -visualtest "My Visual Test"

      2. As part of flag separated by a ":" character, e.g.

         -d:MyDsn -u:admin -p:adminpassword -s:testscript1

         If the parameter contains a space the whole value including the flag
         must be placed in double quotes, e.g.

         "-visualtest:My Visual Test"

         If the parameter starts with a "-" for a "/" character place the whole
         value including the flag in double quotes,e.g.

         "-visualtest:-a visual test"

      3. Password, special case.  The password flag was setup to accept the
         password with no space or ":" following the flag identifier, e.g.

         -pMyPassword

         In this case "MyPassword" is taken as the password.  Note that this
         option does not work with the full name of the flag,e.g.

         -passwordMyPassword

         In this case the password is treated as "asswordMyPassword"

      4. -m(vtvariable) does not use the ":" syntax, the flag and the
         values must be specified as separate parameters, e.g.

         -m "name1=value1"  "name2=value2"

C:\Documents and Settings\user>
</pre>
<p>Now, I will give you an example about how to do this:<br />
Open note pad, and save the following as a batch file, i.e., any name with *.bat, such as &#8220;RunAllVisualTests.bat&#8221;.</p>
<p>tp -u admin -p admin -d &#8220;SQLTestPartner&#8221; -r &#8220;project A&#8221; -t &#8220;visual Test A&#8221; -i<br />
tp -u admin -p admin -d &#8220;SQLTestPartner&#8221; -r &#8220;project B&#8221; -t &#8220;visual Test B&#8221; -i<br />
tp -u admin -p admin -d &#8220;SQLTestPartner&#8221; -r &#8220;project C&#8221; -t &#8220;visual Test C&#8221; -i</p>
]]></content:encoded>
			<wfw:commentRss>http://automation.youplayoff.com/2010/11/11/24/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>#23: Error handling in VBA (TestPartner)_Part2</title>
		<link>http://automation.youplayoff.com/2010/11/01/23/</link>
		<comments>http://automation.youplayoff.com/2010/11/01/23/#comments</comments>
		<pubDate>Tue, 02 Nov 2010 02:13:40 +0000</pubDate>
		<dc:creator>Jia Qi</dc:creator>
				<category><![CDATA[TestPartner (TP)]]></category>
		<category><![CDATA[Error handling]]></category>
		<category><![CDATA[LOOP]]></category>
		<category><![CDATA[On Error GoTo 0]]></category>
		<category><![CDATA[On Error GoTo line]]></category>
		<category><![CDATA[On Error GoTo line label]]></category>
		<category><![CDATA[On Error Resume Next]]></category>
		<category><![CDATA[Resume Line]]></category>
		<category><![CDATA[Resume Line Label]]></category>
		<category><![CDATA[TestPartner]]></category>
		<category><![CDATA[VBA]]></category>

		<guid isPermaLink="false">http://automation.youplayoff.com/?p=362</guid>
		<description><![CDATA[In post#13, we talked about there are 3 error handling statements in Visual Basic of Application (VBA), which can be used in TestPartner. However, NOT all of these statements can be used in QTP, since QTP uses the Visual Basic Scripting Edition (VBScript) scripting language (refer to post#26 for error handling in VBScript). The 3 [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://automation.youplayoff.com/2010/07/01/13-error-handling-in-vba-testpartner/">post#13</a>, we talked about there are 3 error handling statements in Visual Basic of Application (VBA), which can be used in TestPartner. However, NOT all of these statements can be used in QTP, since QTP uses the Visual Basic Scripting Edition (VBScript) scripting language (refer to <a href="http://automation.youplayoff.com/2010/11/24/26-error-handling-in-vbscript-qtp/">post#26</a> for error handling in VBScript).</p>
<p>The 3 error handling statements in VBA are:</p>
<p><strong>1, On Error GoTo <em>line</em></strong><br />
This statement has been used in <a href="http://automation.youplayoff.com/2010/06/11/9-get-data-from-excel-for-qtp-and-test-partner/">post#9</a>.<br />
This statement enables the error-handling routine that starts at line specified in the required line argument. The line argument is any line label or line number. If a run-time error occurs, control branches to line, making the error handler active. The specified line must be in the same procedure as the On Error statement; otherwise, a compile-time error occurs.</p>
<p><strong>2, On Error Resume Next</strong> (see <a href="http://automation.youplayoff.com/2010/07/01/13-error-handling-in-vba-testpartner/">post#13</a> for using &#8220;On Error Resume Next&#8221; with &#8220;On Error GoTo 0&#8243;)<br />
This statement has been used in <a href="http://automation.youplayoff.com/2010/06/29/12-an-example-of-testing-treeview-checkbox-with-testpartner/">post#12</a>.<br />
This statement specifies that when a run-time error occurs, control goes to the statement immediately following the statement where the error occurred where execution continues. Use this form rather than On Error GoTo when accessing objects.</p>
<p><strong>3, On Error GoTo 0</strong> (see <a href="http://automation.youplayoff.com/2010/07/01/13-error-handling-in-vba-testpartner/">post#13</a> for using &#8220;On Error GoTo 0&#8243; with &#8220;On Error Resume Next&#8221;)<br />
This statement has been used in <a href="http://automation.youplayoff.com/2010/06/29/12-an-example-of-testing-treeview-checkbox-with-testpartner/">post#12</a>.<br />
This statement disables any enabled error handler in the current procedure (It doesn’t specify line 0 as the start of the error-handling code, even if the procedure contains a line numbered 0.).</p>
<p>============================================</p>
<p>In <a href="http://automation.youplayoff.com/2010/07/01/13-error-handling-in-vba-testpartner/">post#13</a>, I explained about how to use &#8220;On Error Resume Next&#8221; and &#8220;On Error GoTo 0&#8243; together by analyzing the script from <a href="http://automation.youplayoff.com/2010/06/29/12-an-example-of-testing-treeview-checkbox-with-testpartner/">post#12</a>.</p>
<p>In today&#8217;s post, I will explain how to use &#8220;On Error GoTo <em>Line</em>&#8221; in a loop with &#8220;Resume <em>line</em>&#8220;:</p>
<p>We have an array SheetData(1 To 5) which contains 5 data: A1, B22, C3, D4, E55 (B22 and E55 contains typos, they should be B2 and E5 instead.)</p>
<p>The original code was:</p>
<pre class="brush:vb">
Sub Main()
    ...
    For i = 1 To RowCount
        ComboBox("Parent.Caption=Preferences").Select SheetData(i)
    Next
    ...
End Sub
</pre>
<p>When running the original code, TestPartner will generate run-time errors when try to select SheetData(2)-B22 and select SheetData(5)-E55, since they doesn&#8217;t exist in the ComboBox (B2 and E5 does exist in the ComboBox).</p>
<p>The run-time error will interrupt the run, which is unpleasant. I would like to handle it this way: if SheetData(i) doesn&#8217;t exist in the ComboBox, then write in the test result that &#8220;SheetData(i) doesn&#8217;t exist in the ComboBox&#8221;, do not pop-up the error, and resume to run next i, i.e., try to select SheetData(i+1).</p>
<p>The final code looks like this:</p>
<pre class="brush:vb">
Sub Main()
    ...
    For i = 1 To RowCount
        On Error GoTo ErrorHandler
        ComboBox("Parent.Caption=Preferences").Select SheetData(i)
Jump:
    Next
    ...
Exit Sub

ErrorHandler:
UserCheck "PackageName", False, "The " &#038; SheetData(i) &#038; " does NOT exist."
Resume Jump

End Sub
</pre>
<p>Now, we see how to use &#8220;On Error GoTo <em>Line</em>&#8221; in a loop &#8211; use &#8220;Resume <em>line</em>&#8221; to resume the loop run (The line argument is any line label or line number).</p>
<p>============================================</p>
<p>Below is a more complicated example about how to use &#8220;On Error Resume Next&#8221;, &#8220;On Error GoTo 0&#8243;, &#8220;On Error GoTo <em>Line</em>&#8220;, and &#8220;Resume <em>line</em>&#8221; together.</p>
<pre class="brush:vb">
Sub Main()
...
'Select different Packages from the ComboBox,
'expand Protocol nodes, and check their measurements are enabled
For i = 1 To ColumnCount
    For j = 1 To RowCount
        If j = 1 Then   'First row in the Measurement sheet is package name
            On Error GoTo 0    'Disables error handling in the current procedure
            'in case SheetData(1, i) doesn’t exist in the application
            On Error GoTo ErrorHandlerA
            'Select the package
            ComboBox("Parent.Caption=Preferences").Select SheetData(1, i)
            Dim Package As String
            Package = SheetData(1, i)
        ElseIf j = 2 Then    'Second row in the Measurement sheet is protocol name
            Dim ProtocolPath As String
            ProtocolPath = "\Measurements\" &#038; SheetData(j, i)
            'Report error if the protocol name read from Excel sheet
            'does NOT match the protocol name displayed in the workstation
            On Error GoTo 0    'Disables error handling in the current procedure
            'in case ProtocolPath doesn’t exist in the application
            On Error GoTo ErrorHandlerB
            'Expand Protocol nodes
            TreeView("Parent.Caption=Preferences").SelectItem ProtocolPath, , tpTreeButton
        Else
            'If the Excel cell is not empty,
            'check all the CheckBoxes beside measurement nodes
            If SheetData(j, i) <> "" Then
            Dim MeasurementPath As String
            MeasurementPath = ProtocolPath &#038; "\" &#038; SheetData(j, i)
                'Report error if the measurement name read from Excel sheet
                'does NOT match the measurement name displayed in the workstation
                On Error GoTo 0    'Disables error handling in the current procedure
                'in case MeasurementPath doesn’t exist in the application
                On Error GoTo ErrorHandlerC
                TreeView("Parent.Caption=Preferences").SelectItem (MeasurementPath)

                'Store the mouse y position after "SelectItem", which is always
                'in the middle of the first charactor of the measurement name
                Dim y As Integer
                y = TreeView("Parent.Caption=Preferences").MouseY

                'Handle the situation when the measurement name is longer than
                'the width of the treeview window
                On Error Resume Next    'Handle the situation when there is no scroll bar
                TreeView("Parent.Caption=Preferences").Scroll 0, tpScrollHorizontal
                On Error GoTo 0    'Disables error handling in the current procedure

                'Search if the CheckBoxInTreeView.bmp (13*13 pixels) exists or not
                'Write the results to result summary.
                If TreeView("Parent.Caption=Preferences").BitmapExists("CheckBoxInTreeView", 58, y - 8, 17, 17) Then
                    UserCheck "CheckBoxInTreeView", True, "The " &#038; Package &#038; MeasurementPath &#038; " CheckBox is checked"
                Else
                    UserCheck "CheckBoxInTreeView", False, "The " &#038; Package &#038; MeasurementPath &#038; " CheckBox is NOT checked"
                End If
            End If
        End If
JumpB:
    Next
JumpA:
Next

'Close application to reset its original state
Window.Close

'Erase array
Erase SheetData

Exit Sub

ErrorHandlerA:
UserCheck "PackageName", False, "The " &#038; SheetData(1, i) &#038; " does NOT exist in the Preference Panel - Measurement Tab."
Resume JumpA

ErrorHandlerB:
UserCheck "ProtocolName", False, "The " &#038; SheetData(1, i) &#038; "\" &#038; SheetData(2, i) &#038; " does NOT exist in the Preference Panel - Measurement Tab."
Resume JumpA

ErrorHandlerC:
UserCheck "ProtocolName", False, "The " &#038; SheetData(1, i) &#038; "\" &#038; SheetData(2, i) &#038; "\" &#038; SheetData(j, i) &#038; " does NOT exist in the Preference Panel - Measurement Tab."
Resume JumpB

End Sub
</pre>
]]></content:encoded>
			<wfw:commentRss>http://automation.youplayoff.com/2010/11/01/23/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

