Welcome to TestComplete 7 Made Easy, the new guide to TestComplete 7, the award winning automated testing tool from AutomatedQA Corp. We hope you enjoy the book as much as we, at Falafel Software, enjoyed creating it.
Special thanks to: All the team members at AutomatedQA worldwide for creating a magnificant piece of software in TestComplete 7. The authors also would lik e to thank the Falafel team members in Colorado, Texas and California for their feedback , guidance and recommendations on the subjects of the manual. Falafel would lik e to thank Mr. Derek Langone and Mr. Drew Wells for their trust and belief in the quality of Falafel Software's work .
Technical Editors Noel Rice Drew Wells Cover Designer Matt Kurvin Team Coordinator Lino Tadros Production Falafel Software Inc. Falafel would also lik e to thank Bobby Edgar, Adam Seeley, Andrew Westergren, Ashley Steenbruggen, Gerry McManus, Jim McDonough, Miles Kane, Nick Lord and of course the greatest Nick Olivo for their continuous support and friendship to the entire Falafel team. Last but not least, thank you to all our families for their support and patience while we wrote the book
Table of Contents
Foreword 10
Part I Introduction
12
1 Introduction to TestComplete ................................................................................................................................... 12 2 Who Should Read this Book ................................................................................................................................... 13 3 How the Book is Organized ................................................................................................................................... 13
17
1 Objectives ................................................................................................................................... 17 2 Recording Your First Test ................................................................................................................................... 17 3 Editing a Keyword Test ................................................................................................................................... 20 4 Data Driven Keyword Testing ................................................................................................................................... 24 5 Summary ................................................................................................................................... 34
36
1 Objectives ................................................................................................................................... 36 2 Terminology ................................................................................................................................... 36 3 Types of Testing ................................................................................................................................... 36 4 Before You Begin ................................................................................................................................... 37 5 Your Most Important Test ................................................................................................................................... 39 6 Summary ................................................................................................................................... 40
42
1 Objectives ................................................................................................................................... 42 2 Menus and Toolbars ................................................................................................................................... 42 3 Panels and Workspaces ................................................................................................................................... 44
Project Explorer .......................................................................................................................................................... 44 Object Brow ser .......................................................................................................................................................... 47 Process Tree Pane ......................................................................................................................................................... 48 Object Properties Pane ......................................................................................................................................................... 50 Object Recognition ......................................................................................................................................................... 56 Introduction ......................................................................................................................................... 56 White-Box Applications ......................................................................................................................................... 57 Editor .......................................................................................................................................................... 59 Code Completion ......................................................................................................................................................... 59 Bookmarks......................................................................................................................................................... 60 Editor Options ......................................................................................................................................................... 61 Debugging......................................................................................................................................................... 63 Breakpoints ......................................................................................................................................... 63 Call Stack ......................................................................................................................................... 64 Locals ......................................................................................................................................... 65 Watch List ......................................................................................................................................... 66 Copyright 2009 AutomatedQA Corp. - 2.0 Release
Contents
Visualizer .......................................................................................................................................................... 70 Objectives ......................................................................................................................................................... 70 Enabling the Visualizer ......................................................................................................................................................... 70 Working w ......................................................................................................................................................... 71 ith Visualizer Images
4 Summary ................................................................................................................................... 73
75
1 Objectives ................................................................................................................................... 75 2 Project Anatomy ................................................................................................................................... 75 3 New Project Wizard ................................................................................................................................... 79 4 Hands on Lab: Create a Simple Test ................................................................................................................................... 81 5 Summary ................................................................................................................................... 82
84
3 Summary ................................................................................................................................... 87
89
1 Objective ................................................................................................................................... 89 2 Test Log ................................................................................................................................... 89 3 Emailing Result ................................................................................................................................... 90 4 LockEvents ................................................................................................................................... 91 5 Summary ................................................................................................................................... 92
94
1 Objectives ................................................................................................................................... 94 2 Map to Object ................................................................................................................................... 94 3 Highlight Objects ................................................................................................................................... 99 4 Mapping Dialog ................................................................................................................................... 101 5 Aliases in Scripts ................................................................................................................................... 102 6 Summary ................................................................................................................................... 102
104
1 Objectives ................................................................................................................................... 104 2 Supported Unit Testing Types ................................................................................................................................... 104 3 NUnit Example ................................................................................................................................... 105 4 Hands on Lab: Running a Unit Test ................................................................................................................................... 108 5 Summary ................................................................................................................................... 110
112
TestComplete 7 Made Easy 2 Setting up a Manual Test Project ................................................................................................................................... 112 3 Hands on Lab: Create a Manual Test ................................................................................................................................... 113 4 Hands on Lab: Scripting and Manual Testing ................................................................................................................................... 120 5 Summary ................................................................................................................................... 124
126
1 Objectives ................................................................................................................................... 126 2 Overview ................................................................................................................................... 126 3 Recording Toolbar Anatomy ................................................................................................................................... 127
Adding Text .......................................................................................................................................................... 128 Changing Recording Types .......................................................................................................................................................... 129 Pausing .......................................................................................................................................................... 130 Stopping .......................................................................................................................................................... 130
4 Hands on Lab: Perform a Basic Recording ................................................................................................................................... 130 5 Summary ................................................................................................................................... 131
133
1 Objectives ................................................................................................................................... 133 2 Recording ................................................................................................................................... 133 3 Hands on Lab: MS Paint Test ................................................................................................................................... 136 4 Summary ................................................................................................................................... 140
142
1 Objectives ................................................................................................................................... 142 2 Region Checkpoints ................................................................................................................................... 142 3 File ................................................................................................................................... 150 Comparisons 4 Object Comparisons ................................................................................................................................... 154 5 Hands on Lab: Comparing File, Picture and a Property ................................................................................................................................... 156 6 Summary ................................................................................................................................... 163
165
1 Objectives ................................................................................................................................... 165 2 Overview ................................................................................................................................... 165 3 Modifying Scripts ................................................................................................................................... 165 4 Hands on Lab: Modifying Recording for Data-Driven Testing ................................................................................................................................... 167 5 Summary ................................................................................................................................... 171
173
Contents
4 Hands on Lab: Create Unexpected Window Handler ................................................................................................................................... 177 5 Summary ................................................................................................................................... 181
183
1 Objectives ................................................................................................................................... 183 2 ADO................................................................................................................................... 183 3 Hands on Lab: Query Database ................................................................................................................................... 186 4 Summary ................................................................................................................................... 194
196
1 Objectives ................................................................................................................................... 196 2 Web................................................................................................................................... 196 Page Model 3 Naming Conventions ................................................................................................................................... 197 4 Web................................................................................................................................... 197 Comparison Checkpoint 5 Web................................................................................................................................... 200 Accessibility Checkpoint 6 Finding Web Page Elements ................................................................................................................................... 203 7 Dynamic HTML ................................................................................................................................... 205 8 Hands on Lab: Work with Web Pages ................................................................................................................................... 208 9 Summary ................................................................................................................................... 212
214
1 Objectives ................................................................................................................................... 214 2 Testing against WSDL ................................................................................................................................... 214 3 WebServices Checkpoint ................................................................................................................................... 219 4 WebServices Testing Dialogs ................................................................................................................................... 224 5 XML................................................................................................................................... 226 Checkpoint 6 Hands on Lab: Testing a SOAP 1.2 Web Service ................................................................................................................................... 228 7 Summary ................................................................................................................................... 235
237
1 Objectives ................................................................................................................................... 237 2 Performance Testing Your Web Applications ................................................................................................................................... 237 3 HTTP Load Testing Options ................................................................................................................................... 237 4 Cookie Handling ................................................................................................................................... 239 5 Recording ................................................................................................................................... 239 6 Connections, Requests and Responses ................................................................................................................................... 241 7 Visual Creation of a Load Test ................................................................................................................................... 242 8 Analysis of the Test Log ................................................................................................................................... 244 9 Modifying HTTP Traffic ................................................................................................................................... 246 10 Hands on Lab: Working with HTTP Traffic ................................................................................................................................... 248 11 Summary ................................................................................................................................... 251
Copyright 2009 AutomatedQA Corp. - 2.0 Release
253
1 Objectives ................................................................................................................................... 253 2 Installing Remote Agent ................................................................................................................................... 253 3 Running Remote Agent ................................................................................................................................... 253 4 Configuring Remote Agent ................................................................................................................................... 255 5 Hands on Lab: Working with Remote Agent for HTTP Load Testing ................................................................................................................................... 257 6 Summary ................................................................................................................................... 261
263
1 Objectives ................................................................................................................................... 263 2 Network Suites ................................................................................................................................... 263 3 Hosts ................................................................................................................................... 265 4 Jobs/Tasks ................................................................................................................................... 266 5 SynchPoints ................................................................................................................................... 267 6 Setup ................................................................................................................................... 268 7 Summary ................................................................................................................................... 274
276
1 Objectives ................................................................................................................................... 276 2 Creating ................................................................................................................................... 276 3 Scripting ................................................................................................................................... 278 4 Summary ................................................................................................................................... 278
280
284
1 Keyboard Shortcuts ................................................................................................................................... 284 2 Code Completion ................................................................................................................................... 286 3 Keyboard Handling in Recorder ................................................................................................................................... 287 4 Global Shortcuts/Changing Keyboard Emulation ................................................................................................................................... 288
292
298
Contents
Index
300
10
Foreword
Foreword
TestComplete is more than just a test automation tool it does that, of course, but it also integrates all the other aspects of testing from organizing your manual tests, to doing unit testing and functional testing, and all the way to performance and load testing. Thats already a daunting amount of functionality, and then on top of that TestComplete supports multiple programming languages and platforms and it comes out of the box bundled with support for a long list of third party components. I almost forgot you can also write your scripts in any of several standard scripting languages, too. Thats a lot of ground to cover. Its easy to get started with TestComplete, but to take full advantage of everything that it has to offer you need not only to understand the built-in functionality, but you also need a deep knowledge of your testing trade and software development best practices. Anyone writing a book on TestComplete had better have that kind of depth and experience. To be honest, there just arent that many experts in this field that have such experience and are also proficient and entertaining technical writers. When I first heard a new book on TestComplete was going to be written I crossed my fingers that the superstar team at Falafel Software would be involved in some way. I just cant think of anyone more appropriate for the task. Now that Ive reviewed the first manuscript, I can see that I was right (again). This book is terrific. It will definitely end up on the nightstands of all discerning TestComplete users. I strongly recommend it to everyone from novices just getting their feet wet, to expert testers ready to go to the next level. Finally, my deepest respects go to Lino Tadros, founder and CEO of Falafel software, for his expertise and his appreciation that all work and no fun is no way to go in life, and especially in testing. Thank you, Lino, for such a fine book and even more, thank you for being my friend and knowing all there is to know about Ouzo.
Part
I
Introduction
12
1
1.1
Introduction
Introduction to TestComplete
About TestComplete Today automated testing plays a vital role in many software development projects. Automated testing has long been thought critical for large software development organizations, but is often considered to be too expensive and difficult to implement for smaller companies. AutomatedQAs TestComplete breaks this stereotype. It delivers automated functional, unit, regression, manual, data-driven, object-driven, distributed and HTTP load, stress and scalability testing in one easy-to-use and totally integrated package at an affordable price. TestComplete is a full-featured environment for automated testing of Windows, .NET, Java, WPF (XAML) applications, web pages, web servers and web services. It has been designed to free developers and QA departments from the massive drain on time and energy required by manual testing. TestComplete offers systematic, automated, and structured testing, with superior support for .NET, Java, Visual C++, Visual Basic, WPF (XAML), Delphi, C++Builder and web applications. It is equally oriented for testing 32-bit and 64-bit applications. With TestComplete you can also test PowerBuilder, FoxPro, Access and other applications. TestComplete is the ultimate solution to perform nightly tests and to help you get reliable daily builds of your software. TestComplete tools and features let every member of your team, developers and nondevelopers, no matter how technically savvy, contribute to your testing projects. Once you start using TestComplete, you will be able to turn every test run into a key contribution to your overall development efforts. TestComplete will keep your projects on schedule and on spec, the team confident, and the work 100% productive. With TestComplete you and your team can implement comprehensive software testing strategies, automating the non-automatable for maximum return on investment: In my opinion, [TestComplete] is a must-have tool for any software developer who believes in applying a rigorous testing methodology to his products. The ability to work with Visual C++, Visual Basic, C++Builder, Delphi, Java and .NET applications means that youre virtually getting several tools in one, and the wide variety of scripting languages means you can work in whatever language youre most comfortable with. Even if you have no interest in automated testing procedures, [TestCompletes] fascinating ability to automate the non-automatable is sure to find a use on your desktop! Dave Jewell, Delphi Magazine
Introduction
13
1.2
1.3
TestComplete IDE
This section introduces the basic tools you need to work effectively with TestComplete, including an exploration of the TestComplete environment and debugging basics.
Project Items
This section provides an overview of all project item types with additional detail on the Tested Application.
Test Log
This section discusses the test log and the types of messages available in TestComplete. We will learn how to email the test log and also how to reduce the size of the test log.
Name Mapping
This section introduces Named Mappings and Aliases used to handle long object identifiers and to provide identifiers with meaningful names.
Unit Testing
14
This section discusses unit testing, the types of unit test frameworks supported by TestComplete and provides an example of using an NUnit unit test.
Manual Testing
This section looks at the structure of a TestComplete project and the parts that make up the various testing functionality included in a project.
Data-Driven Testing
This section covers how the Data Driven Testing plug-in consumes common data types.
Event Handling
This section explains how to respond to events that occur during testing and explains how to handle unexpected windows.
WebServices Testing
This section demonstrates how to test a web service, including how to import web service meta data, calling simples methods, creating web service types and calling complex methods. This section also explains how to create a web service checkpoint.
Introduction
15
Remote Agent
Remote Agent is a tool that allows for the distribution of HTTP loads tests across a network of computers. This section explains how to install, configure and run Remote Agent.
Distributed Testing
This section explains how tests are run on several computers at the same time.
User Forms
This section demonstrates how to create user forms and manipulate them using scripts.
Best Practices
This section contains notes on best practices for testing in general and web pages in specific.
Cheat Sheet
Here you'll find a handy reference to TestComplete general keyboard shortcuts, shortcuts for Code Completion, keyboard handling in the recorder, how to change global shortcuts and how to change keyboard emulation.
Part
II
Keyword Testing
Keyword Testing
17
2
2.1
Keyword Testing
Objectives
In this section we'll take a look at the Keyword Testing features of TestComplete and you will learn how to: Record Keyword tests Add a checkpoint to a test Convert a recorded test to a Data Driven Test The goal of Keyword Testing is to get developing testcases rapidly and in this chapter we'll do exactly that by developing a frequently requested testcase scenario using Data Driven testing.
2.2
Record a New Test Test from the TestCom plete Start Page
You will be prompted to create a new project. In the Project Name field type: Keyword
18
Click Create
As soon as you click Create the TestComplete main window is hidden and you'll see the recording toolbar:
Keyword Testing
19
1. Select Order | New Order to view the Order dialog 2. Increment the Quantity to 2 by clicking on the up arrow of the UpDown control 3. Type: "Jon Doe" in the Customer Name field, "123 Easy" in the street field, "CA" in the State field and "95060" in the Zip field 4. Finally click the OK button to save the order
Order dialog
Now, click the Stop button on Recording toolbar (the blue square icon) and the TestComplete main window will reappear with the Keyword Test Editor open. Congratulations, you've now recorded your first Keyword test! TestComplete should now look like this:
20
2.3
Keyword Testing
21
Notice as you read through the Test Steps we recorded it's easy to make sense of the various operations. The Keyword Testing feature is very powerful and automatically leverages other features of TestComplete such as NameMapping, Aliases and TestedApps whereas in previous versions you had to configure each of these features manually prior to recording.
Record a new test Append operations to an existing test Run a Keyword test Add Variables and Parameters to the test Manipulate Test Steps (move up/down, indent/outdent steps) Edit a test description
22
The Test Steps tree allows you to manipulate the test by adding, deleting and editing steps. The Test Steps tree supports many standard editing operations such as Undo, Redo, Select All, Cut, Copy and Paste available from the right click menu or main menu. As is typical with recorded tests you'll want to review the results of the recording and tidy up the test by removing any unnecessary or redundant steps. Next, we do just that and illustrate how easy it is to edit Keyword tests. Deleting Unnecessary Steps In our recorded test you'll notice TestComplete created a step reading "Run TestedApp Orders" and as you can see from the Project Explorer we now have an Orders subnode listed under TestedApps that it launches. As a result, we can delete the steps recorded to manually launch the Orders application in favor of using the Run TestedApp step. To do that simply: 1. Click the first step of the test starting with Explorer 2. Holding the Shift key down press the down arrow to highlight all of the steps up to, but not including the Run Tested Apps step 3. Press the Delete key to delete them from the test
At this point, you've completed your first test now, click the Run Test button on the toolbar and watch the results! Adding a Checkpoint Operation to a Test Next, we'll add a Checkpoint operation to our test verifying the Total field on the Order dialog reflects the correct value (Quantity x Price). To verify this data we're going to use a Checkpoint operation and add it to our test after we've performed the data entry on the quantity field. To add a checkpoint perform the following actions: 1. Click the Search box at the top of the Operations palette 2. Type: property 3. Drag the item Property Checkpoint onto the Steps tree and drop it on the step where we set the Quantity to display the Create Property Checkpoint dialog
Keyword Testing
23
4. Click on the Orders application and select Order | New Order to display the Order dialog 5. Use the Finder Tool on the Create Property Checkpoint dialog to select the Total edit box on the Orders dialog
6. On the Create Property Checkpoint dialog click Next 7. Type: "wText" (without quotes) into the Search edit box at the top right hand of the dialog and click Next 8. Change the Value to "200" (without quotes) and click Finish Your Keyword Test should now contain a step that looks like the If ... Then step below:
24
2.4
Keyword Testing
25
To create this text file: 1. Start Windows Notepad 2. Enter the data pictured above 3. Save the file to disk as "names.csv" Adding the CSV File to the Files Store Next, we need to add this file to our Files Store. 1. From the TestComplete Project Explorer expand the Stores node, right click the Files subnode and select New Item
26
2. On the Add File dialog locate names.csv and add it to the Files Store Modifying our Keyword Test to Perform Data Driven Testing Now that we have data to work with we can modify our test making it data driven. Here are the tasks we need to perform: Initialize the CSVDriver Create a loop that will iterate over all of the data Indent our test steps to use the loop Modify our data entry steps to use the data from the CSVDriver Add a step to move to the next record Let's walk through each of these tasks: 1. Under Test Actions we'll add the Call Object Method operation by dragging it onto the Orders step:
Keyword Testing
27
2. On the Call Object Method dialog enter "DDT" (without the quotes) as the object and click Next >
28
4. Click the ellipsis (...) next to the Filename parameter, select Code Expression from the Mode dropdown and enter a Value of Files.FileNameByName('names.csv') then click OK
Keyword Testing
29
5. Click the Finish button to complete the Call Object Method step Next, we'll add some logic to iterate over our data. 1. On the Operations palette under Statements select While Loop and drop it onto the Orders step.
2. The While Loop dialog will appear and click the ellipsis (...) under the Value1 column then select Code
Copyright 2009 AutomatedQA Corp. - 2.0 Release
30
Expression from the Mode dropdown and enter a Value of: DDT.CurrentDriver.EOF() then click OK
3. Click on the edit box on under the Value2 column type false then click OK
Now, we need to nest our existing test steps under the While Loop step by indenting the remaining steps.
Keyword Testing
31
1. Click the Orders step 2. Holding the Shift key down use the down arrow to multi-select the remaining test steps 3. Click the Indent button on the Keyword Editor Toolbar
Next, we need to change our data entry steps to use values from the CSVDriver. We'll walk through changing the Customer data entry field and you can repeat the steps for the Street and Zip fields. 1. Double click where it says "Jon Doe" to display the On-Screen Action dialog 2. Click the ellipsis (...) under the Value column to display the Edit Parameter dialog 3. On the Mode dropdown select Code Expression and change the Value to read DDT.CurrentDriver. Value('name') then click OK then Finish
32
4. Repeat the same steps for the Street and Zip edit fields only changing the parameter passed to DDT. CurrentDriver.Value(...) to reflect the correct field.
At this point, we're almost done, the only thing remaining is to add a step that will move the CSV record pointer to the next row of data. 1. On the Operations palette select Test Actions then drag and drop the Run Code Snippet operation to the very bottom of our Keyword Test
Keyword Testing
33
2. For the code snippet use DDT.CurrentDriver.Next() then click OK 3. Finally, click the Indent button on the toolbar to indent our Run Code Snippet step and we're done! Your test should look like this:
34
2.5
Summary
In this chapter we covered Keyword Testing including recording and editing Keyword Tests. You should be familiar with how to record Keyword tests and edit them using the Keyword Test Editor.
Part
III
Overview of Testing and TestComplete
36
3
3.1
3.2
Terminology
First, let's define a few terms to help facilitate a discussion on testing: QA - the Quality Assurance team R&D - the Research and Development team developing the application being tested Build - a specific revision of the application under test that is submitted to QA Application - the code that will be tested using TestComplete
3.3
Types of Testing
Manual Testing
Manual Testing is where a tester methodically exercises the features of a product or product area without the aid of test automation. The single greatest strength of manual testing is that it is truly real-world testing, meaning that the tester can utilize the application under test the same way an end user would. Through manual testing the tester can provide a wide variety of feedback about the application under test not limited to simply reproducing bugs. The major weakness of manual testing is that it is time consuming, tedious and requires extended periods of very focused attention which can be very difficult to perform on a regular basis. Manual testing tends to be quite error prone, leading to situations where consistently reproducing a bug can be very difficult.
Functional Testing
Functional Testing focuses on interactions with an application's user interface (UI) via the mouse, keyboard or other input device with particular attention to how the application visually responds to input. The goal of Functional Testing is to methodically cover all of the various UI features exposed by an application. Functional Testing should be highly organized and structured in a manner that allows for additional tests to easily be incorporated as new features are added.
37
Unit Testing
Unit Testing is testing that focuses on smaller atomic portions of an application. Typically, Unit Testing requires internal knowledge of how an application performs and seeks to test portions (objects, methods and function) of an application in isolation. In many cases, applications have to be designed with Unit Testing in mind in order for this type of testing to be truly effective. The benefit of unit testing is that it tends to force application developers to write smaller more well defined routines with fewer dependencies allowing for more highly specific tests to be developed.
Regression Testing
Regression Testing is the process of executing tests in a repeatable manner and comparing the latest results with previous test executions to ensure that the same outcome is achieved. Regression Testing is extremely important and is the means of realizing the value of test automation. Repeatedly executing tests over time allows you to verify the application is still performing in the manner in which it was intended.
Distributed Testing
Distributed Testing is the act of farming different portions of a test out to separate machines for execution. Distributed Testing is useful for simulating real world interactions on a networked application such as a web site or web service and can exercise functionality designed to handle concurrent use of application resources including, but not restricted to data.
Multi-Tier Explained
In software development there are typically three Tiers which are used to describe various aspects of an application they are Client Tier, Middle Tier and Data Tier. These are each defined as: Client - The user interface or presentation of an application and it's data which is typically covered through Functional Testing. Data Tier - The storage of an application's data which can be exercised by Functional Testing as well as Unit Testing Middle Tier - Refers to the portion of the application responsible for moving data back and forth between the Client and the Data Tiers. The code that resides in this Tier can be tested from either the Client Tier via Functional testing or through Unit Testing on the code in the Middle Tier itself. Keep in mind that these are not strict rules as to which type of testing should be used but more illustrative how the different types of testing can be used.
3.4
38
In TestComplete 7, a new automatic NameMapping feature has been added to make this even easier.
39
lots of options including some excellent Open Source projects which are freely available like Subversion, otherwise known as SVN. While it's beyond the scope of this document to discuss the specific merits of source control it's a subject that shouldn't be ignored.
3.5
40
3.6
Summary
To best leverage your investment in test automation it's important to plan your overall testing strategy. Before diving in and unleashing the full power of TestComplete be sure to organize your communication strategy. Make communicating your results an important part of judging the success of your efforts. Also, treat your test development like any other software development project and use the tools available to maintain the quality and integrity of your test code.
Part
IV
TestComplete IDE
42
4
4.1
TestComplete IDE
Objectives
This section introduces the basic tools you need to work effectively with TestComplete. In this section you will: Get familiar with the TestComplete environment. Locate the Menus, Toolbars, Workspace areas, Object Browser and Project explorer. Gain a solid understanding of the Object Browser. Get familiar with the TestComplete Code Editor and all its features. Gain the necessary knowledge of debugging in the TestComplete Editor.
4.2
TestComplete IDE
43
TestComplete Toolbar
The TestComplete Toolbar is an easy way to get at TestComplete functionality or deeper menu items with only one click. Saving files, adding new units, recording, playing back, debugging, searching, formatting, etc...
The great thing about the toolbar is that it is customizable. So if you ever use a TestComplete functionality often and you don't see it on the toolbar, add it by right clicking on the toolbar and choose customize. Click on the Commands tab and drag any functionality you desire to anywhere on the toolbar. Once you drag a
44
4.3
4.3.1
TestComplete IDE
45
The Project Workspace consists of two main windows, The Project Explorer and the Code Explorer.
46
TestComplete IDE
47
The Project Explorer will allow you to see all projects in a suite and all the specific Project Items that are part of a specific Project. If you ever missed a Project Item from the Wizard at startup, you can always right click on a Project in the Project Explorer and choose Add New Item, where you will be presented with all TestComplete Project plug-ins to add to the project. The Code Explorer on the other hand, is a different view into your code base that enables you to navigate easily between functions in large files, rename functions, delete functions, sort functions by name in the tree, etc...
4.3.2
Object Browser
The Object Browser is the most powerful part of TestComplete. It is where all the brains behind the TestComplete muscle reside. When you click on the Object Browser Window in TestComplete, the engine monitors all running processes on your machine and extracts vital information about each process for display as you can see below. You
48
can filter the kind of processes you need to inspect or eliminate a category of processes by right-clicking on the Object Tree below on the left and filter processes. The Object Browser can also examine your system as a hardware unit and report on the CPU, CPU count, amount of memory (RAM) on the machine, operating system in use, and other useful information, from a testing perspective.
4.3.2.1
Process Tree Pane The Process Tree Pane enables you to view all currently running processes on the machine and its toolbar on top allows you to filter the processes from running application to system processes to chosen testapps applications in your TestComplete project.
TestComplete IDE
49
By Right clicking anywhere in the Object Tree Pane, the popup menu appears with options to refresh the content of the tree, filter, terminate, copy to editor, sort and other useful functionality that we will discuss later in this chapter.
50
4.3.2.2
Object Properties Pane From the Object Tree Pane, invoke the 3rd menu option from the top called Object Properties..., that will invoke the following dialog when you need to quickly dissect a window on the screen.
TestComplete IDE
51
As a Lab for this part of the chapter, let's use the Object Browser, Object Tree Pane and Object Properties dialog to work with a Notepad window: 1. Open Notepad from the Windows directory or System32, depending of the version of Windows you are running. 2. View the Object Browser in TestComplete to determine that the process of Notepad has been detected by the Object Tree.
52
Notice that the process of Notepad is displaying three windows underneath the process and the Properties of the process itself are displayed on the right. The main Notepad window is actually the 3rd one down. The other two windows (IME and MSCTFIME UI) are other non-visible windows in Notepad for language direction reasons like Hebrew and Arabic, etc... 3. To make sure that the main window of Notepad is the 3rd one underneath the process, right click on it and choose Highlight on the Screen.
TestComplete IDE
53
Note: The Notepad application is brought to the front and the main window starts flashing with a red rectangle around the main window several times. 4. Notice in the Properties window that the properties that you can change have a small grey circle on the left of them. That means these properties are READ-WRITE as far as the Object Browser is concerned, all the other ones are READ ONLY and you will not be able to change their values in the Object Browser.
54
5. One of the properties of that main window in Notepad is called "WndCaption" and it has the gray circle next to it. That means it can be written to from the Object Browser. This property is actually the title of the window. Push the CTRL key and click inside of the edit area of the property. 6. Type "Welcome to TestComplete 7" and press [Enter].
7. Now go back to the Notepad application and view the title area of the application.
TestComplete IDE
55
Don't worry, you did not change Notepad forever :) it is only for this session until it is shutdown and started up again. 8. Now let's use the Finder tool to capture the Edit window in Notepad (The white area only with no Notepad title or menus). 9. Invoke the Object Properties dialog from the popup menu of the Object Tree. Drag the Finder tool to the white area in Notepad until you see a red rectangle around the edit portion only.
10.The Object Properties will automatically refresh and show all the properties TestComplete was able to see from the Window object in memory.
56
The button pointed to by the number 1 above will allow you to highlight the window object in-place in the Object Tree Pane as part of the Object Browser. This is a very handy button when your application windows are numerous and have a deep hierarchy as is the case for Internet Explorer. The button pointed to by number 2 above will allow you to highlight the object on the screen by flashing it several times, similar to step 3 above. 4.3.2.3 Object Recognition
4.3.2.3.1 Introduction
From the previous sample with Notepad, you probably noticed that TestComplete recognized a lot of properties of the main Notepad window as well as the Edit window. On the other hand, you probably also noticed that the Fields and Events tab were blank. Even the Methods tab had only methods pertaining to standard TestComplete functionality and actions. So where are Notepad's methods, Fields and events? Well, TestComplete will recognize objects and will go as deep as the application will allow it to. That means, it is based on how the application was built, developed or compiled as to what TestComplete will be able to see inside of it. This brings up the topic of White Box Applications Vs. Black Box Applications. TestComplete will be able to automatically see deeply inside .NET and Java application without any changes to the application just because of the nature of metadata generation of .NET and Java application which are easy to reflect. Reflection is the ability to retrieve internal objects, properties, methods and events. So these are always called White Box Applications.
TestComplete IDE
57
And with the introduction of TestComplete 7, Delphi, C and C++ application do not need to be compiled with a special header to making it a White Box tested application. TC 7 enables these application by default.
While viewing the Object Browser, you will notice sometimes that a TestComplete icon will show next to a specific process. That sign identifies the process as "OPEN" and means TestComplete can reflect its content and get as much Runtime Type Information as possible.
In this sample, I used Visual Studio 2008 to generate a very simple C# based Windows application that adds two numbers together
58
In case you don't have Visual Studio, the executable is available through the book download as "TCDotNetApp.exe".
Notice that TestComplete automatically figured out that we are dealing with a .NET application so it started using the built in "WINFORMSOBJECT" identifier to make it easier to reach all .NET methods, fields, events and properties associated with the application. At this point, if we had a function in the TCDotNetApp.exe called "Hello" that was never called from the User Interface, it will still show up in the Methods tab. We would be able to call it directly from the script and it will be visible to TestComplete via reflection. Note: TestComplete has many built in recognition objects for Delphi VCL objects, Java Swing objects,
Copyright 2009 AutomatedQA Corp. - 2.0 Release
TestComplete IDE
59
4.3.3
4.3.3.1
Editor
Code Completion The Code Editor in TestComplete is easy to use and productive to get the job done. One of the first features you will discover and love in the TestComplete Editor is the Code Completion feature. I am not sure how we used to write code before this feature was introduced in major development tools and in TestComplete. Instead of having prior knowledge of the objects you need to deal with in TestComplete or have access to the Help files, it is simple enough to let TestComplete do the job for you by entering the name of an object and placing a "." period after the object. That will invoke the Code Completion window with all properties, methods and events available for that object. Sometimes you even have the need to invoke the Code Completion window in the middle of a statement. That is possible using the handy keyboard shortcut CTRLSPACE.
Another great feature of the TestComplete Editor is the Parameter Completion feature. For example, when you need to know the count and type of a parameter that TestComplete recognizes, you can always open a parenthesis and key in CTRL-SHIFT-SPACE to bring up the Parameter completion window:
60
4.3.3.2
Bookmarks Another great feature of the editor in TestComplete is the ability to place bookmarks in script units opened in the IDE and be able to jump between them by a simple keystroke. You can set a bookmark by having the cursor on that line and pressing CTRL - SHIFT - and a number between 1 and 9. NOTE: The project in the screenshot below is for illustration purposes only, to work with Editor Bookmarks you can use any of the courseware projects or create a new project.
In the figure above, please notice that the bookmarks are set on lines 5,15 and 18 (see the yellow glyph in the gutter). Also, the Bookmarks window at the bottom of the editor will list all set bookmarks with their numbers, their unit names and their line numbers. To jump to a specific bookmark at any time, press CTRL
TestComplete IDE
61
- 0 to 9 (without the SHIFT). To delete a bookmark, delete from the bookmark window or press CTRLSHIFT- 0 to 9 again while the cursor is on the bookmark. 4.3.3.3 Editor Options From Tools | Options, you can get to the Editor options under Panels | Code Editor:
Under Display, you have the choice to change the Text specifications, background colors and margin, gutter styles and capacity and also whether you want to show line numbers or not. Another very useful feature of the editor in TestComplete is the ability to set Code Templates.
62
Every scripting language has it own templates. Above you will see that I added a new Template called TCTraining that contains a function name "test" with a comment in it. The script itself can be anything that you expect to use a lot in your testing. Notice also the little pipe "|" sign inside the brackets. The pipes indicates the position of the cursor in the code after the template has been inserted. Now lets go back to the editor and try to enter this template: 1. Choose an empty area between two functions and press CTRL - J. The following code template helper will appear:
TestComplete IDE
63
2. Choose the TCTraining Template from the list and press Enter. The code is inserted in the script unit and the cursor is blinking right before the comment starts.
4.3.3.4
Debugging
4.3.3.4.1 Breakpoints
The Debugger capabilities in the TestComplete's Editor are very helpful in finding script errors, flow problems and also to evaluate the values of local and global variables.
64
The Breakpoints window in TestComplete is very easy to use. You can set breakpoints in your editor by clicking in the gutter next to the line you want to set a breakpoint on or by pressing F5 while the cursor is on that line. In the Breakpoints window you can: Enable or disable a specific breakpoint. That is better than deleting them and reentering them all over based on different debug sessions. View the Location of the unit name it resides in and also the line number of where it resides. Include a description to explain the goal behind using the breakpoint. Finally, you have two powerful features in the breakpoints window which are Pass Count and Condition. If you are debugging a "For Loop" that goes on for 1000 iterations, knowing that it will fail some time after 900 times, it would be wise to place a Pass Count of 900 on the breakpoint instead of having to step over the breakpoint 900 times. When the pass count is not known but a condition has to be met, the Condition property can be set (e.g: x > 100).
4.3.3.4.2 Call Stack
The Call Stack window is very helpful when your scripts get called one from the other in a long chain of execution. During a break in execution, the Call Stack window will show the order of execution for the calling functions to get to that point of execution. The figure below shows the Call Stack at a break in execution. Usually that is good information for pinpointing the offending procedure. Unfortunately, in many cases "X" does not mark the spot like in an Indiana Jones' movie, so the problem you are trying to figure out
Copyright 2009 AutomatedQA Corp. - 2.0 Release
TestComplete IDE
65
has already manifested itself way before the break in execution occurred. These are tougher bugs to figure out.
4.3.3.4.3 Locals
The Locals window is an easy and fast way to monitor the value of local variable inside of a specific function. Like in the figure below, we created 2 local variables, "myString" and "myNumber", and assigned specific values to both. To view their values, you only need to open the Locals window and they will be there as long as you are breaking inside of the function that contains them. So how do you view values of variables that are not local to a function? That is the functionality of the Watch List.
66
Notice in the screenshot below that the Global variable "myGlobal" did not show up in the locals window. This is correct, as the myGlobal variable is not a local of that function.
TestComplete IDE
67
To evaluate the myGlobal variable, go to the Watch List window and add a new item by right-clicking in the window.
The output in the Watch List window will allow you to monitor the value of that variable during the life of the execution session.
68
You can also use the Evaluate command available from the debug menu item in the editor:
TestComplete IDE
69
70
4.3.4
4.3.4.1
Visualizer
Objectives In this section we'll take a look at TestComplete's Visualizers feature and you will learn how to: Enable Visualizers Work with Visualizer Gutter icons The Visualizer can be particularly useful when providing feedback to people unfamiliar with a particular test script. The recorded screenshots function as a storyboard for the script allowing the person reviewing the results to more quickly understand what actions caused the problem.
4.3.4.2
Enabling the Visualizer The Visualizer records screenshots during recording or script playback allowing you to see exactly where the action took place. By default TestComplete's Visualizer feature is turned off and requires that you manually enable it in order to capture Visualizer data. To enable the Visualizer select Tools | Options... and select Engines | Visualizer:
TestComplete IDE
71
Visualizer Options
You can enable the Visualizer before recording and/or before playback. You and also specify what part of the screen will be captured using the Capture Style.
4.3.4.3
Working with Visualizer Images Once you have enabled the Visualizer for recording and/or playback you will see cues in the Script Editor gutter indicating images have been captured. Notice in the picture below lines 18, 20 and 23-25 all have a image icon displayed in the editor gutter:
72
Double clicking these image icons will display the Visualizer Images dialog allowing you to peruse the captured images. The dialog displayed below appeared after double clicking the Visualizer icon in the gutter on line 20 from the script above where you can clearly see the Orders | New Order... menu item was clicked.
TestComplete IDE
73
4.4
Summary
In this chapter: You got a tour of the TestComplete environment. Located the Menus, Toolbars, Workspace areas, Object Browser and Project explorer. Gained a good understanding of the Object Browser. Got familiar with the TestComplete Code Editor and all its features. Gained the necessary knowledge for debugging in the TestComplete Editor.
Part
V
Projects and Suites
75
5
5.1
5.2
Project Anatomy
In TestComplete a Project is a container of test scripts and other Project Items used by the tests that make up the project. A Project Suite is a container of projects providing a mechanism to logically group related projects. To create a new project select File | New | Project... and you will be presented with the Create New Project dialog:
This is a much simplified dialog than previous versions of TestComplete that asks only for the Project Name, the scripting language to use and the location to save the project. If you would like to use the "classic" Create New Project dialog, feel free to click on the "Classic" button
76
The "Classic" Create New Project dialog presents you with a number of pre-configured Project Templates that are geared towards specific types of testing. The templates are: General Purpose Test Project - useful for a wide variety of test scenarios Object Driven Testing - for working with custom data structures Unit Testing - for running MSTest, NUnit, JUnit, DUnit or TestComplete unit tests Distributed Testing - for managing test execution of projects on different computers HTTP Load Testing - for load testing web server applications [All Items] - template that includes all of TestComplete's available Project Items Once you click OK on the Create New Project dialog you will be presented with the Project Wizard which allows you to further customize your New Project. For more details refer to the following section on the New Project Wizard. After creating a new project you can view all of its Project Items and sub items from the Project Explorer.
77
The various parts of a project are as follows: MyProjectSuite - A Project Suite MyProject - A Project Name Mapping Script - A Project Item Stores Tested Apps Unit1 - A Project Item Element
78
Projects
Projects can contain the following: Project Items: Provide support for a specific type of testing. Project Item Elements: The child nodes that represent testing functionality of the Project Item or serve to organize its contents. Folders: Provides a means of organizing Project Items and Project Item Elements within a Project. When a project is initially created you have the opportunity to specify which Project Items you want included. You can add and remove Project Items at any point. Adding them at the time a project is created is a matter of convenience. Both Project Suites and Projects provide a logical view of the files and folders that make up the project. When removing nodes from the Project Explorer you are only removing them from this logical view. The actual files and folders are not deleted from disk and may be added back to the project using the right-click context menu and selecting Add | Existing Item...
Project Items
Project Items make up the specific types of testing functionality or assist in performing various test operations. TestComplete includes a large collection of Project Items covering a wide variety of test functionality. You can easily add and remove Project Items using the right-click menu on the Project node
Copyright 2009 AutomatedQA Corp. - 2.0 Release
79
5.3
80
Project Templates
Initially, accepting the defaults on this dialog will be the preferred choice until you're familiar enough with the available Project Items and can identify the ones you use most frequently at which point you can create a Project Template. To define a new template select the Project Items you use most frequently and click the Save As... button to create a new Project Template that will be available on the Create New Project dialog.
81
- Tested Applications 5. In the left hand column on the dialog click Tested Applications 6. At the bottom of the Items list click the Add button to add a specific Windows application to test against 7. On the Create New Item dialog fill in the name of your application and click Next 8. In the Tested application edit box, type the complete filename including the path to the Windows application you wish to test, or use the ellipsis (...) button to select the application 9. Click the Finish button 10. In the left hand column of the dialog click Select Project Items 11. Click the Save As... button 12. On the Save Template dialog enter a Template Name and Description and click OK to create a new project template that you can reuse
5.4
82
2. Select General Purpose Test Project and click the OK button 3. On the New Project Wizard click the Finish button, accepting the defaults
5.5
Summary
In this chapter we covered the structure of a TestComplete project and the parts that make up the various testing functionality included in a project. You should be familiar with how to construct a Project Template for use across your organization for greater consistency and ease of use when creating new test projects.
Part
VI
Project Items
84
6
6.1
Project Items
Objectives
This section provides an overview of all project item types with additional detail on the Tested Application.
6.2
Project Items
The Project Wizard Select Project Items tab allows you to select which project items are included in the project.
ActiveX - This project item allows you to load an ActiveX object in TestComplete's memory space and use that object in your tests. For example you could use the Microsoft ADO Data Control to work with databases. Events - This project item is used to hook to TestComplete events (and those of other application, such as ActiveX controls). This item is required. HTTP Load Testing - Necessary for the creation of a load on a web server using TestComplete. Keyword Testing - Allows for the visual construction of scripting blocks to help build logic without being familiar with code syntax. Low-Level Procedure Collection - A virtual folder for holding low-level (screen coordinate based tests) procedures.
Project Items
85
Manual Test - A virtual folder for holding manual tests. Name Mapping - Used to map the name of an object to a shorter name (aliasing). Network Suite - Used in distributed testing. ODT - Object Driven Testing used to add pseudo class structure to script code. Script - Holds a collection of script units. THIS ITEM IS REQUIRED. Stores - Holds collections of checkpoints used in a project Unit Testing - A virtual folder for holding Unit Tests. User Forms - A virtual folder for holding User Forms (Forms presented to the user during the test run, such a progress dialog, etc). Web Services - A virtual folder for holding connection, methods and type of web services (Information from the WSDL file). Tested Application - Holds information for managing the Application(s) under test.
6.2.1
Tested Applications
The screenshot below shows the configuration of a tested applications project item:
Icon - Show the icon associated with the tested application Launch - If checked, this application will be run if TestedApps.RunAll command is used (either from script or context menu). Name - Is the name that TestComplete uses to refer to the tested application (must be a name that the scripting language can handle). File Name - Is the name of the application on the disk. Count - This is the number of instances of the application that TestComplete will launch. If the application is already running TestComplete will post a warning message in the Test Log. File Path - By default, File Path is the relative path to the file name from the TestComplete project. Run Mode - How the application is launched. Parameters - Allows parameters to be set using the ellipses button.
Run Mode
Simple - Launches the application under the same user account as TestComplete. Parameters can be passed in Simple mode.
86
RunAs - Launches the application under the user account specified by the parameters dialog.
Debug - Launches the application under the same user account as TestComplete, then TestComplete attaches to the application as a "debugger". The stack trace of any exception that occurs in the application while the test(s) are being run will be recorded in the TestLog. This option requires debug information in the application under test. Profile - Launches the application inside of AQTime using the profile (or AQTime project) specified in the parameters dialog. For example code coverage profiling could be used to see how much of the code is being tested by your automated tests.
Project Items
87
6.3
Summary
In this section we had a brief overview of the project items of TestComplete. We also looked at the Tested Application project item in more detail.
Part
VII
Test Log
Test Log
89
7
7.1
Test Log
Objective
This section discusses the test log and the types of messages available in TestComplete. We will learn how to email the test log and also how to reduce the size of the test log. In this section you will: Learn about the basic Test (Results) Log. How to view the Test Log in Internet Explorer. How to reduce test log size using LockEvents. Learn how to email the test log.
7.2
Test Log
Logs are used to persist feedback from your tests including errors, warning messages and events as well as entire files and images. Logs are stored in a directory as XML files.
Log Tree
This area will have a node for each Test Item level used to run the test. In the image above, for example, a project suite was run. The project suite is the top (root) node and each project is represented by the child of the project suite. The statuses of child items in the tree bubble up to the parent items. In the screenshot above you can see that errors flagged in child level items (the red X indicates the error status) have bubbled up to the project suite node. The context menu for the Log Tree contains menu items to handle the log output including Export to IE, Send Email and the ability to view closed Log Panels.
90
Test Log
This area contains messages coming from both TestComplete and the script code. There are six different types of messages: Message - Can come from TestComplete or from the script code (Log.Message), will not cause the test to fail. Warning - Can come from TestComplete or from the script code (Log.Warning), not necessary a failure for the test but could be an indicator for why a test failed. Error - Can come from TestComplete or from the script code (Log.Error), this indicates a failure for the test. Events - Usually comes from TestComplete but can come from the script as well (Log.Event), does not cause the test to fail. TestComplete generates an event for every mouse-click or keyboard entry in the test. Image - Usually comes from script code (Log.Picture) but TestComplete can generate as well (Region Checkpoints). File - There are two types of File log items. Log.File, will copy the file into the directory holding the log XML file and creates a hyperlink to the file. Log.Link just creates a hyperlink to the file without copying the file. The test log area may have a hierarchical structure via creating and pushing log folders onto the log (Log. AppendFolder, Log.CreateFolder/Log.PushLogFolder, Log.PopLogFolder). All messages by default go into the last pushed log folder (i.e., the top of the stack).
7.3
Emailing Result
Sending the result via email can be done either by script code (see help file for examples) or after the test run by selecting Send via Email... from the Log Tree context menu. Selecting Send via Email... creates an email with a multi-part hypertext file attachment. To preview what this file will look like, select View Results in IE from the context menu. View Results in IE also shows how TestExecute will display Test Results after a test run.
Test Log
91
7.4
LockEvents
With any long running test, the test result log will be filled with hundreds if not thousands of events.
92
Most of the time, the tester is not interested in events unless there is a problem in the test run. TestComplete can eliminate events unless an error occurs. By adding Log.LockEvents to the script code, no events will be placed into the test log unless an error occurs. By default the last 20 events are logged, but this can be changed by adding a parameter to the Log.LockEvents command.
7.5
Summary
In this section we learned about the test log and the different type of messages available in TestComplete. We learned how to email the test log and also how to reduce the size of the test log.
Part
VIII
Name Mapping
94
8
8.1
Name Mapping
Objectives
This section introduces Name Mapping and Aliases used to handle long object identifiers and to provide identifiers with meaningful names. In this section you will learn about: Named Mapping. Aliases and how they are different from Name Mapping How TestComplete uses Alias and Name Mapping.
8.2
Map to Object
TestComplete 7 provides automatic Name Mapping and Aliases to tame extremely long object identifiers that have somewhat unclear default names. For example:
Sys.Process("Hello").Panel1.Panel2.Container1.Container2.button1
Clearly there are numerous issues with this identifier, its long and awkward not to mention we have no clue about the purpose or identity of "Container1", "Container2" or "button1". Named Mappings allow you to rename Panel1, Panel2, Container1, Container2 and button1 to useful names like MyPanel, myInsidePanel, myTabs, myPages and btnSubmit. The issue here is that you still need to type:
NameMappings.Sys.Process("Hello").MyPanel.myInsidePanel.myTabs.myPages.btnSubmit
TestComplete 7 creates an Alias to represent this long string. If you create the Alias "btnSubmit", you only need to type:
Aliases.btnSubmit
Consider the Orders.exe applications that comes as an example with TestComplete 7, located under Vista in "C:\Users\Public\Documents\TestComplete 7 Samples\Open Apps\OrdersDemo\C#\bin\Debug":
Name Mapping
95
For Example, if I want to have access to the header control in the table, TestComplete already sees the header as "Sys.Process("Orders").WinFormsObject("MainForm").WinFormsObject("OrdersView").Window ("SysHeader32", "", 1)" but in TestComplete 7, during recording, the automatic NameMapping feature takes place and records the mapping as "NameMapping.Orders.MainForm.OrdersView.SysHeader32" which makes it much easier to understand and work with in scripts.
96
The main difference between the NameMapping section and the Aliases section is the fact that the Name Mapping has to respect the parenthood of the hierarchy of the controls on the form, but the Aliases section can make the line of script much smaller by creating a specific Alias to a specific control that can be referred to anytime directly in the script. So, with that said, we can access the Header Control in 3 different ways based on the example above: v Sys.Process("Orders").WinFormsObject("MainForm").WinFormsObject("OrdersView").Window ("SysHeader32", "", 1) v NameMapping.Orders.MainForm.OrdersView.SysHeader32 v Aliases.Orders.MainForm.OrdersView.SysHeader32
But we can also drag the SysHeader32 from the NameMapping Section to the Aliases Section to make it at the same level as "Sys" like so:
Name Mapping
97
That would allow us to access the Header in a fourth way as: Aliases.SysHeader32 In this way, Aliases allow you to ignore on-screen objects that were used for design but are not necessary to the test automation process.
Let's say now you need to manually add the Toolbar to your Name Mapping Project Item: From the Object Browser tab, right click on the Toolbar window item and choose "Map the Object Name"
98
The Object Name Mapping Window appear that allow you to specify a new name for the Toolbar, if you wish, give it a description, and mainly select the properties that would make the component unique on the form. By moving properties from the "Available" list to the "selected" list, it make TestComplete identify that control on the form by these attributes. Of course, the more properties you select the more unique the control would be. The reason that is important is the fact of what happens if there are TWO controls at the same ownership level with the same selected properties that are equal to each other, how does TestComplete know how to differentiate between them at runtime when the script is run? That is why it is very important that you differentiate between your instances of controls or components with the least amount of properties (for speed) to make the call in the script not ambiguous.
Name Mapping
99
8.3
Highlight Objects
During mapping or after the fact, objects being referred to can be highlighted on the screen. In the Name Mapping dialog, this is done by pressing the Highlight button.
100
In the NameMapping project item editor, highlighting is done by selecting Highlight on Screen from the context menu (right-clicking).
Name Mapping
101
8.4
Mapping Dialog
The parts of the Mapping dialog are listed below:
Mapped Name - lets you define the name for an on screen object Description - short note about the object Selected Properties - the properties that are used to define this on screen object for name mapping. Available Properties - additional properties that can be use to help refine the name mapping. Template Name - which template that TestComplete used to define the Selected Properties initially. Select - if the on screen object matches one than one possible template, this button allows you to choose which template to use. Templates - Allows you to add/edit Templates. Highlight - Highlights the currently selected object on the screen if possible. OK - Add the selected object to both the Mapped Objects and the Aliases sections of the NameMapping project item. Skip - Add the selected object to the Mapped Objects only.
102
Cancel - Cancel the mapping at this point (all items mapped before will still be mapped). Help - Brings up the help on this dialog.
8.5
Aliases in Scripts
If you are recording a script and have the NameMapping project item in the current project, TestComplete will first try to use the Aliases project item in the recording. If that does not work, it will use the NameMapping project item. In manual coding you can use the Aliases as well. If the Alias object is available in the Object Browser, then TestComplete will present all the properties and methods for that object. If the object is not available in the Object Browser, TestComplete will present a smaller subset of methods and properties. This can be changed in the Options dialog (Tools | Options| Engines | Name Mapping) by selecting the Store CodeCompletion Information. This does increase the size of the NameMapping project item file but allows you to code without having the tested application open.
8.6
Summary
We learned about what name mapping is and what it is used for. The difference between Aliases and Name Mapping was explained. And we learned how to map an object from the screen.
Part
IX
Unit Testing
104
9
9.1
Unit Testing
Objectives
This section discusses unit testing, the types of unit test frameworks supported by TestComplete and provides an example of using an NUnit unit test. In this section you will: Learn about the types of unit test framework supported by TestComplete. See an example of using a Unit Test.
9.2
Unit Testing
105
9.3
NUnit Example
NUnit is a popular .NET unit testing framework (available at http://www.nunit.org). When it is installed, it includes a sample unit test assembly. 1. Add a Unit Testing Project Item to your project. 2. Add a NUnit Project Item under the Unit Testing Project Item.
106
3. Click the ellipses button for the Assembly file name. Add the Assembly that holds the NUnit tests. 4. Push the OK button. This will open the NUnit editor in TestComplete.
Unit Testing
107
The screenshots below show sample output and logging for the test run.
108
9.4
5. Add a "Unit Testing" Project Item 6. Add a "TCUnitTest" Project Item to the "Unit Testing" Project Item.
Unit Testing
109
8. Select the "UnitTestingDemo" Process. 9. Select the Mode of "Run selected tests only". 10.Click the Load button. 11.Uncheck the "ShowNum" Method (this method has a UI which we do not want to handle in a unit test). 12.Click Run on the "TCUnitTest1" Project Item.
110
Most of the work for Test Cases in the Unit Test is done by the developer in the Application.
9.5
Summary
We learned about the types of unit test frameworks supported by TestComplete and how to use an NUnit unit test.
Part
X
Manual Testing
112
10
10.1
Manual Testing
Objectives
This section discusses TestComplete's Manual Testing features, how to construct a simple manual test using one of the provided sample applications and how to interact with manual tests from scripts. In this section you'll learn: What a Manual Test is How to setup a Manual Test Project How to create a Manual Test How to use script within a Manual Test
10.2
Manual Testing
113
10.3
114
2. Select General-Purpose Test Project Template and click OK 3. On the Project Wizard dialog click Unselect All and then check Manual Test and Tested Application
Manual Testing
115
4. Click Finish
116
4. Change Test caption to "Manual Test" and Test description to "Hands on Lab" 5. Under Test instructions type "Orders application must be running to complete this test" 6. Under Test Steps right-click and select Preview Step Dialog... (click Yes on the prompt to save the dialog)
Manual Testing
117
118
button and set the caption to "Add Order and Verify Quantity"
5. Enter the following Step Instructions: a. Select Order | New Order... from the main menu b. Enter 2 in the Quantity Field c. Verify that the Total Field equals 200
Manual Testing
119
120
10.4
Manual Testing
121
7. With the cursor at the end of TestedApps type a period "." to invoke the Code Complete again and select Orders 8. Type another period and select Run 9. Press Return to add a new blank line below TestedApps.Orders.Run() 10.Press Ctrl-Space to display the Code Completion window 11.Select ManualTest1 12. Type "." and select Start 13. Press Return to add a new line below ManualTest1.Start 14. Press Ctrl-Space to display the Code Completion window 15. Select TestedApps 16. Type a period "." and select TerminateAll
122
3. In the Workspace under Available Events expand the Manual Testing Events node
Manual Testing
123
4. Double click the OnBeforeStep event to add the event to your test 5. Under Events to Handle scroll the list down and locate the Manual Testing Events node 6. Click on the OnBeforeStep item then click the New button
7. Click OK on the New Routine dialog to add a new function to the Unit1 test script 8. In your Unit1 script file add a new blank line below the function declaration and type 'BuiltIn. ShowMessage("Hi from script")'
9. Run the Project and click the Begin Test button. Notice the ShowMessage dialog appears:
124
10.5
Summary
In this section, we learned about TestComplete's Manual Testing features and constructed a simple manual test using one of the provided sample applications. We also illustrated how you can interact with manual tests from scripts.
Part
XI
Basic Record and Playback
126
11
11.1
11.2
Overview
TestComplete has rich Record/Playback functionality allowing you to quickly record new test scripts. TestComplete has several options that allow you to control how recording is performed. To view/change these options select Tools | Options... and click the Engines folder and select Recording. You should see the following options:
127
11.3
The buttons are as follows: Add Comment to Test Run Tested Application
128
Run a Script Extension Add Checkpoint From the List Start Recording Stop Recording Pause Recording Record Keyword Test Record Low Level Procedure (screen coordinates) Record Low Level Procedure (window coordinates) Record Script Record an HTTP Task More Details Clicking the More Details button will expand the toolbar so that it displays Parent and Object name data for the item underneath the mouse cursor.
Starting a Recording
To start a recording you must have a project loaded. You can load an existing project or start a new project. Once you have a project loaded there are two ways to begin a new recording: 1. Selecting Test | Record from the TestComplete main menu 2. Press the Record toolbar button on the Test Engine toolbar:
129
Notice there is a checkbox at the bottom that allows you to indicate that the text is to be inserted as a comment. There is also a Pick Object... button that allows you to insert a line of code that references a specific onscreen object.
The different recording types are: Record a Keyword Test Record Low Level Procedure based on screen coordinates Record Low Level Procedure based on window coordinates Record a Script (default) Record an HTTP task To switch the type of recording simply click the appropriate button.
130
11.3.3 Pausing
TestComplete allows you to pause in the middle of a recording by clicking on the Pause button. Pausing a test allows you to manipulate the application under test or change the environment without recording any of those actions into the script. To resume a paused test click the Start Recording button.
11.3.4 Stopping
To stop a recording click the Stop button. Clicking the Stop button will close the Recording toolbar and restore the TestComplete main window leaving you in the Code Editor on the newly recorded script.
11.4
131
2. Click the
3. Click the Windows Start button 4. Select Run... 5. Type "notepad.exe" and click the OK button 6. Once Windows Notepad starts type "this is a test from TestComplete" 7. Click the Stop button on the recording toolbar to end the recording
11.5
Summary
In this section you learned how to perform basic record and playback tasks. We discussed the functionality available on the toolbar including how to record various types of activity.
Part
XII
Low Level Procedure
133
12
12.1
12.2
Recording
The reason you want to use the Low Level Procedure feature in TestComplete is when the need arises for recording specific mouse or keyboard operations on the screen for playback that are not automatically recorded during a regular recording session. For example, if TestComplete would record every mouse and keyboard operation automatically during each recording session, we would have ended up with thousands of lines of script identifying the mouse movement coordinates and clicks, while in most cases these are not necessary. On the other hand, if you are trying to Paint in a program like MS Paint or trigger a Hover event inside of Internet Explorer or Firefox, it is very much necessary that the recorder brings in the valuable mouse and keyboard coordinates, clicks and keystrokes. 1. Start a new project normally in TestComplete as shown in the figure below:
134
2. Make sure to enable Low Level Procedure Collection in the Project Wizard. If you forget, no worries. You will still be able to add it to the project after the fact using the Add New Item menu of the project in the Project Explorer.
135
3. When you start a recording session in TestComplete, you are presented with the recording tool bar shown below. On the recording tool bar are two buttons that enable Low Level Procedure recording: The Screen Coordinates based button, which automatically set the coordinates for the recording as (0,0) to be the top most left of the screen. The Window Coordinates based button, which sets the (0,0) coordinates starting from top most left window under recording. Tip: For a smoother playback and easier implementation between different resolutions on the screen, we recommend the "Window Coordinates" button to be used.
136
12.3
137
9. Upon completion of your masterpiece, stop the recorder from the TestComplete recording toolbar. 10.Notice that TestComplete did not record any of the clicks on the MS Paint application, but added one line of code to function Test1 to execute the collection of mouse movements and clicks collected during the recorded session.
138
11.TestComplete collected all the mouse movement and clicks from the recorded session into an LLCollection item in the project called "MSPaintCollection" (see above). 12.Double click the MSPaintColection item in the project Explorer. 13.Notice the 900 + entries that were added to the collection to record all the mouse movement and clicks.
139
14.Each record contains the mouse operation (down, up, move), the number of the operation, the event name itself, the parameters of the mouse at that time (X & Y coordinates) and finally the delay in milliseconds between operations. 15.The nice thing about this workspace area is that you are able to modify 1 or a bunch of these 900 records at will. You can reduce the amount of time between operations, delete meaningless mouse movements that are not needed or even change the mouse coordinates on the screen after the fact.
140
You can now try to playback the recording by running the routine. What happened? Are you surprised? Well, you probably saw the mouse moving on top of the TestComplete Editor in a pattern exactly as you expected would happen in MS Paint. That is because nothing caused the MS Paint application to come to the front or be activated. To fix that issue for your script, always activate the window that needs to be focused and top-most before running your low level procedures.
12.4
Summary
In this section we covered how and when to use a Low Level Procedure, recording choices, editing a recording and used the Low Level procedure workspace to change coordinates, delays and events. We also fixed a situation where the testing environment did not work as first expected.
Part
XIII
Stores and Checkpoints
142
13
13.1
13.2
Region Checkpoints
Region Checkpoints allow for the comparison of an area of the screen with a baseline. The baseline is stored in the Project Item called "Regions" under the Project Item called "Stores". A Region Checkpoint can be created either while recording or from the toolbar at test design time.
143
144
145
7.
146
8.
147
9. The tolerance property is measured in PIXELS and will allow you to define how many pixels can differ between the two regions before the compare would error out. 10.Name the picture "imageLogo" and click OK in the "Create Region Checkpoint" dialog. 11.Copy the code into a method in TestComplete.
[VBScript] Sub RegionCompareExample If (Not Regions.Compare("imageLogo", Aliases.Sys.iexplore.pageGoogle.imageLogo, False, False, True, 0)) Then Call Log.Error("The regions are not identical.") End If End Sub
[JScript] function RegionCompareExample() { if(!Regions.Compare("imageLogo", Aliases.Sys.iexplore.pageGoogle.imageLogo, false, false, true, 0)) Log.Error("The regions are not identical."); }
148
14.Notice that the Tooltip saying "Google" is part of the image 15.Run the method again. There will be an error in the test log.
149
The log results show: The first picture in the log is the expected image (the one stored in the Region project item). The second picture in the log is the actual image. The third picture in the log (the one shown) is the difference between the two images (shown in red pixels).
Copyright 2009 AutomatedQA Corp. - 2.0 Release
150
[JScript] function PictureCompareExample() { if (!Sys.Process("iexplore"). Page("http://www.google.com/").Table(0). Cell(1, 0).Link(0).Image("nav_r1_c1").Picture(). Compare(Regions.GetPicture("Logo"))) { Log.Error("The OnScreen Object is different") } }
13.3
File Comparisons
TestComplete can compare files using: A simple byte by byte comparison (Checkpoint) of two files. Comparing file hash values (see Hash Values below). A third-party difference engine. Settings for the third party difference engine can be set through Tools | Options to open the Options dialog, then select Engines | Stores.
151
152
3. Select two files to compare. You can find them either on disk or using the "Files" Project Item. 4. If you know the files are different and want to compare them, click the "Calculator" button next to the Hash value edit box. 5. Press the OK button. 6. Copy the code to a new method.
[VBScript] Sub FileCompareExample If (Not Files.Compare("Sample1.txt", "Sample2.txt", 0, True)) Then Call Log.Error("The files are not identical.") End If End Sub
[JScript]
153
function FileCompareExample() { if(!Files.Compare("Sample1.txt", "Sample2.txt", 0, true)) Log.Error("The files are not identical."); }
[XML (Test.XML)] <?xml version="1.0" standalone="yes" ?> <Contacts> <Contact> <Name>Eric</Name> <Company>Falafel</Company> <Phone>888 GOT-FALAFEL</Phone> </Contact> <Contact> <Name>Lino</Name> <Company>Falafel</Company> <Phone>888 GOT-FALAFEL</Phone> </Contact> <Contact> <Name>Drew</Name> <Company>AutomatedQA</Company> <Phone>(978) 236-7900</Phone> </Contact> <Contact> <Name>Derek</Name> <Company>AutomatedQA</Company> <Phone>(978) 236-7900</Phone> </Contact>
154
If there are known difference between files, you can still compare the files by using a hash value. To compare these two files, the code would look like the example below: Caution: The order that the files are compared makes a difference in the calculated Hash Value. For example, consider the two xml files below. The hash value from TestComplete if "Contacts.XML" is the first file in the comparison is 1812515919, if "Test.XML" is the first file the hash value is 1883158225. So the order of the comparison makes a difference in what the final hash value used in the Compare() function is.
[VBScript] Files.Compare("Contacts.XML","Test.XML",1812515919,True)
[JScript] Files.Compare("Contacts.XML","Test.XML",1812515919,true)
13.4
Object Comparisons
Object Comparisons allow the comparison of multiple properties of an Onscreen Object (and the children of that object, if desired). Create Object Checkpoint can be invoked with either the recording toolbar or the "Tools" toolbar:
155
If the object had children, TestComplete will ask if you want to save the properties of the child objects.
Depending on the type of OnScreen object, TestComplete will select certain properties for you for comparison. Any of the unselected properties can be added for comparison.
[VBScript] Sub ObjectCompareExample If (Not Objects.Compare(Sys.Process("iexplore"). Page("http://www.activefocus.net/").Panel(0), "Panel", True)) Then Copyright 2009 AutomatedQA Corp. - 2.0 Release
156
[JScript] function ObjectCompareExample() { if(!Objects.Compare(Sys.Process("iexplore"). Page("http://www.activefocus.net/").Panel(0), "Panel", true)) Log.Error("The objects are not identical."); }
TestComplete will report the difference on the first object found with difference only.
13.5
157
12.Click the Add button on the Add Text to Script dialog. 13.Add a new contact (+ button) and enter contact information. 14.Save as "Test.XML" (File | Save). 15.Click Create File Checkpoint in the recording toolbar 16.Select "Contacts.XML" as the first file. 17.Select "Test.XML" as the second file. 18.Press the OK button. 19.Click the Add button on the Add Text to Script dialog. 20.Close the "StoresSampleProgram" program. 21.Stop the recording.
[VBScript] (Your recording maybe different) Sub Test1 Dim p1 Dim w1 Dim w2 Dim w3 Dim w4 Dim w5 TestedApps.StoresSampleProgram.Run Set p1 = Sys.Process("StoresSampleProgram") Set w1 = p1.Form1 Call w1.StripMainMenu.Click("File|Open...") Set w2 = p1.Window("#32770", "Open Contacts XML") Call w2.Window("SHELLDLL_DefView").Window("SysListView32", "FolderView"). ClickItem("Contacts.xml", 0) w2.Window("Button", "&Open").ClickButton Call w1.StripMainMenu.Click("File|Save...") Set w2 = p1.Window("#32770", "Save Contacts File") Call w2.Window("ComboBoxEx32").Window("ComboBox").Window("Edit"). Keys("Test.XML") w2.Window("Button", "&Save").ClickButton If (Not Files.Compare("Contacts.xml","C:\Training\Stores\Test.XML",0,True)) Then Call Log.Error("The files are not identical.") End If Set w2 = w1.WinFormsObject("panel1") Set w3 = w2.toolStrip1 Call w3.ClickItem("+") Set w3 = w1.WinFormsObject("dataGridView1") Call w3.ClickCell(4, "Name") Set w4 = w2.textBox1 Call w4.Click(17, 11) Call w4.Keys("Test[Tab]") Set w4 = w2.textBox2 Call w4.Keys("Test") Set w5 = w2.textBox3 Call w5.Click(15, 6) Call w5.Keys("Test") Call w4.Click(71, 4) Call w3.ClickCell(3, "Name")
158
Call w1.StripMainMenu.Click("File|Save...") p1.Window("#32770", "Save Contacts File").Window("Button", "&Save"). ClickButton p1.Window("#32770", "Save Contacts File", 1).Window("Button", "&Yes"). ClickButton If (Not Files.Compare("Contacts.xml", "C:\Training\Stores\Test.XML", 0, True)) Then Call Log.Error("The files are not identical.") End If w1.Close End Sub
[JScript] function Test1() { var p1; var w1; var w2; var w3; TestedApps.StoresSampleProgram.Run(); p1 = Sys.Process("StoresSampleProgram"); w1 = p1.Form1; w1.StripMainMenu.Click("File|Open..."); w2 = p1.Window("#32770", "Open Contacts XML"); w2.Window("SHELLDLL_DefView").Window("SysListView32", "FolderView"). ClickItem("Contacts.xml", 0); w2.Window("Button", "&Open").ClickButton(); w1.StripMainMenu.Click("File|Save..."); w2 = p1.Window("#32770", "Save Contacts File"); w2.Window("ComboBoxEx32").Window("ComboBox").Window("Edit").Keys("Test.XML"); w2.Window("Button", "&Save").ClickButton(); if(!Files.Compare("Contacts.xml", "C:\\Training\\Test.XML", 0, true)) Log.Error("The files are not identical."); w2 = w1.WinFormsObject("panel1"); w3 = w2.toolStrip1; w3.ClickItem("+"); w1.WinFormsObject("dataGridView1").ClickCell(4, "Name"); w3 = w2.textBox1; w3.Click(52, 5); w3.Keys("Test"); w3 = w2.textBox2; w3.Click(53, 11); w3.Keys("Test"); w2.Click(205, 102); w3 = w2.textBox3; w3.Click(52, 7); w3.Keys("Test"); w1.StripMainMenu.Click("File|Save..."); p1.Window("#32770", "Save Contacts File").Window("Button", "&Save"). ClickButton(); p1.Window("#32770", "Save Contacts File", 1).Window("Button", "&Yes"). ClickButton(); if(!Files.Compare("Contacts.xml", "C:\\Training\\Test.XML", 0, true)) Log.Error("The files are not identical."); w1.Close(); }
159
23.Run the new method. The test log will show a file comparison error.
160
6. Push the "OK" button. 7. Click the "Add" button in the "Add Text to Script" dialog. 8. Close the "StoresSampleProgram" 9. Stop the recording. 10.Run the new method.
[VBScript] Sub Test2 Dim p1 Dim w1 Dim w2 TestedApps.StoresSampleProgram.Run Set p1 = Sys.Process("StoresSampleProgram") Set w1 = p1.Form1 Call w1.StripMainMenu.Click("File|Open...") Set w2 = p1.Window("#32770", "Open Contacts XML") Call w2.Window("SHELLDLL_DefView").Window("SysListView32", "FolderView"). ClickItem("Contacts.xml", 0) w2.Window("Button", "&Open").ClickButton If (Not Regions.Compare("WinFormsObject_dataGridView", Sys.Process("StoresSampleProgram").WinFormsObject("Form1"). WinFormsObject("dataGridView1"),False, False, True, 0)) Then Call Log.Error("The regions are not identical.") End If w1.Close End Sub
161
var p1; var w1; var w2; TestedApps.StoresSampleProgram.Run(); p1 = Sys.Process("StoresSampleProgram"); w1 = p1.Form1; w1.StripMainMenu.Click("File|Open..."); w2 = p1.Window("#32770", "Open Contacts XML"); w2.Window("SHELLDLL_DefView").Window("SysListView32", "FolderView"). ClickItem("Contacts.xml", 0); w2.Window("Button", "&Open").ClickButton(); if(!Regions.Compare("WinFormsObject_dataGridView", Sys.Process("StoresSampleProgram").WinFormsObject("Form1"). WinFormsObject("dataGridView1"),false, false, true, 0)) Log.Error("The regions are not identical."); w1.Close(); }
162
2. Run the "StoresSampleProgram" 3. Open "Contacts.XML" in the StoresSampleProgram" (File | Open...) 4. Click the "Create Property CheckPoint"
6. Click the ellipse button (...) on the Property textbox. 7. Select the "RowCount" property.
163
[JScript] function Test3() { var p1; var w1; var w2; var w3; TestedApps.StoresSampleProgram.Run(); p1 = Sys.Process("StoresSampleProgram"); w1 = p1.Form1; w1.StripMainMenu.Click("File|Open..."); w2 = p1.Window("#32770", "Open Contacts XML"); w3 = w2.Window("SHELLDLL_DefView").Window("SysListView32", "FolderView"); w3.ClickItem("Log", 0); w3.ClickItem("Contacts.xml", 0); w2.Window("Button", "&Open").ClickButton(); if(Sys.Process("StoresSampleProgram").WinFormsObject("Form1"). WinFormsObject("dataGridView1").RowCount != 5) Log.Error("The property value does not equal the template value."); w1.Close(); }
13.6
Summary
In this section we learned about Region (Images) and how to compare two regions. We learn how TestComplete compares files. And also how to compare multiple properties of an OnScreen object.
Part
XIV
Data-Driven Testing
Data-Driven Testing
165
14
14.1
Data-Driven Testing
Objectives
This section covers how the Data Driven Testing plug-in consumes various common data types. In this section you'll learn about: The data driven plug-in. The different type of drivers available. How to modify a script to use a driver.
14.2
Overview
The Data Driven Plug-In (DDT) uses ADO to access different data elements, such a text files, Excel Spreadsheets, or any ADO compatible database. Once a driver has been initialized, the DDT plug-in provides a common interface to columns and rows in the data source. These methods/properties are: ColumnCount: The number of columns in the data source. ColumnName: The name of a given column from the data source. Name: The Name of the Driver. Value: Returns the value of a column based on the column name or index. EOF: Indicates if the driver is at the end of the data source. DriveMethod: Iterates through all the records of the database, and executes a script routine for each record. Next: Move to the next record in the data source The DDT plug-in supports the creation of three different types of drivers, CSVDriver, ExcelDriver, and ADODriver: CSVDriver is used to read text files, such as comma delimited (default) or tab delimited (using a schema.ini file). By default the first row is the header information (or column names) for the driver.
Example: Case,User,Password 1,"admin","admin" 2,"user1","pass1"
ExcelDriver is used to read an Excel spreadsheet. The first row of the sheet is the header information for the driver. ADODriver is a generic driver to read in ADO compatible data source.
14.3
Modifying Scripts
You can modify a simple data entry script to use an outside data as an input source. For example suppose we have a script that enters a word into notepad:
166
Sub Test1 Dim p1 Dim w1 Dim w2 Set p1 = Sys.Process("Notepad") Set w1 = p1.Window("Notepad", "*") Set w2 = w1.Window("Edit") w2.VScroll.Pos = 0 Call w2.Click(144, 26) Call w2.Keys("TestComplete") End Sub
[JScript] function Test1() { var w1; w1 = Sys.Process("notepad").Window("Notepad", "*").Window("Edit"); w1.VScroll.Pos = 0; w1.Click(274, 105); w1.Keys("TestComplete"); }
We can modify the script to enter in multiple words from an outside data source. In the example below we create a list of customers from the AdventureWorksDB:
[VBScript] Dim MyDriver Sub Main Dim SQLStatement Dim ConnectionString ' Start Notepad TestedApps.Notepad.Run ' Limit to 100 records SQLStatement = "SELECT TOP (100) CustomerID, FirstName, LastName FROM" & _ " Sales.vIndividualCustomer" ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;" & _ "Persist Security Info=False;" & _ "Initial Catalog=AdventureWorks;Data Source=.\SQLExpress" ' Create Driver Set MyDriver = DDT.ADODriver(ConnectionString,SQLStatement) ' Call Method 100 times MyDriver.DriveMethod("Unit1.Test1") End Sub Sub Test1 Dim p1 Dim w1 Dim w2 Dim KeyStr Set p1 = Sys.Process("Notepad") Set w1 = p1.Window("Notepad", "*") Set w2 = w1.Window("Edit") w2.VScroll.Pos = 0 ' Create String with Customer Information KeyStr = MyDriver.Value("CustomerID")& "," & _
Data-Driven Testing
167
MyDriver.Value("FirstName")& "," & _ MyDriver.Value("LastName")& "[Enter]" Call w2.Keys( KeyStr) End Sub
[JScript] var MyDriver function Main() { try { var SQLStatement; var ConnectionString; // Start Notepad TestedApps.Notepad.Run(); // Limit to 100 records SQLStatement = "SELECT TOP (100) CustomerID, FirstName, LastName FROM" + " Sales.vIndividualCustomer"; ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;" + "Persist Security Info=False;" + "Initial Catalog=AdventureWorks;Data Source=.\\SQLExpress"; // Create Driver MyDriver = DDT.ADODriver(ConnectionString,SQLStatement); // Call Method 100 times MyDriver.DriveMethod("Unit1.Test1") } catch(exception) { Log.Error("Exception", exception.description); } } function Test1() { var w1; var KeyStr; w1 = Sys.Process("notepad").Window("Notepad", "*").Window("Edit"); w1.VScroll.Pos = 0; w1.Click(274, 105); KeyStr = MyDriver.Value("CustomerID")+ "," + MyDriver.Value("FirstName")+ "," + MyDriver.Value("LastName")+ "[Enter]"; w1.Keys(KeyStr); }
As you can see there is very little modification of the initial recording needed to make it ready for Data Driven Testing. Most of the work is in the setup of the driving method. This example illustrated connecting to an MS SQL database using an ADO Driver.
14.4
168
3. Under the Stores Project Item, right-click the Files and select Add New Item 4. Add the TestData.txt and the Schema.ini files to the Stores, and click Yes on the Add Files to Stores dialog. 5. Run the "All Pairs Sample" application. 6. Click Record in TestComplete 7. Select 10 from the track bar in the sample application
10.Check mark the Greedy checkbox. 11.Click the Run Button 12.Select Fair Share from the Allocation Strategy Combo Box again. This is important for later as this causes the error message to be posted into the correct test case.
Data-Driven Testing
169
w1 = Sys.Process("All Pairs Sample").MainForm; w1.WinFormsObject("trackBar1").wPosition = 10; w2 = w1.WinFormsObject("comboBox1"); w2.ClickItem("Fair Share"); w1.WinFormsObject("comboBox2").ClickItem("All Stores"); w1.WinFormsObject("checkBox3").ClickButton(); w1.WinFormsObject("button1").ClickButton(); w2.ClickItem("Fair Share"); }
14.Modify the checkbox line to get rid of the call to Click Button() substitute Checked = true. See the example code snippet below.
[VBScript] w1.WinFormsObject("checkBox3").Checked = true
15.We now need to create a routine for reading the data file. In the main routine add a new line. 16.Type in "DDT.CSVDriver()" 17.Move the cursor inside the parentheses, type in "Files.FileNameByName()" 18.Inside the FileNameByName parentheses, type in TestData.txt (including the quotes). 19.Add a new line. 20.Type in "DDT.CurrentDriver.DriveMethod()". 21.In the parentheses, add Unit1.Test1. Your script should now look something like the example below:
[VBScript] Sub Main DDT.CSVDriver(Files.FileNameByName("TestData.txt")) DDT.CurrentDriver.DriveMethod("Unit1.Test1") End Sub
[JScript]
function Main() { DDT.CSVDriver(Files.FileNameByName("TestData.txt")); DDT.CurrentDriver.DriveMethod("Unit1.Test1"); }
170
w1.WinFormsObject("trackBar1").wPosition = DDT.CurrentDriver.Value("Iterations") Call w1.WinFormsObject("comboBox2"). ClickItem(DDT.CurrentDriver.Value("Stores")) Set w2 = w1.WinFormsObject("comboBox1") Call w2.ClickItem(DDT.CurrentDriver.Value("Strategy")) w1.WinFormsObject("checkBox3").Checked = (DDT.CurrentDriver.Value("Greedy") = "Y") w1.WinFormsObject("button1").ClickButton Call w2.ClickItem("Fair Share") Log.PopLogFolder() End Sub
[JScript] function Test5() { var w1; var w2; Log.AppendFolder(DDT.CurrentDriver.Value("case")); w1 = Sys.Process("All Pairs Sample").MainForm; w1.WinFormsObject("trackBar1").wPosition = DDT.CurrentDriver.Value("Iterations"); w2 = w1.WinFormsObject("comboBox1"); w2.ClickItem(DDT.CurrentDriver.Value("Strategy")); w1.WinFormsObject("comboBox2").ClickItem(DDT.CurrentDriver.Value("Stores")); w1.WinFormsObject("checkBox3").Checked = (DDT.CurrentDriver.Value("Greedy") == "Y"); w1.WinFormsObject("button1").ClickButton(); w2.ClickItem("Fair Share"); Log.PopLogFolder(); }
23.Run the project. Caution: DO NOT TOUCH THE COMPUTER WHILE THE TEST IS RUNNING. There will be an unexpected window during the test run that TestComplete will handle.
The test log should look something like the example screenshot below:
Data-Driven Testing
171
14.5
Summary
In this section we learned about how the DDT plug-in works and the different types of drivers. We learned how to modify a script to get values from the DDT driver.
Part
XV
Event Handling
Event Handling
173
15
15.1
Event Handling
Objectives
This section explains how to respond to events that occur during testing. In this section you'll learn about: What Events are. How to create script code that responds to an event. How to respond to unexpected windows.
15.2
174
Occurs just before TestComplete send an HTTP request to the tested Web Server. Occurs just after TestComplete receives a response to an HTTP request.
Description Occurs before the next step is display to the user Occurs when TestComplete get the information about what the next step is to be executed Occurs when a manual test is about to be resumed. Occurs when a user click the Fail button in the Step Dialog Occurs when a user click the Success button in the Step Dialog Occurs when the manual test is suspended Occurs when the user stops the manual test.
NetworkSuite Events Name OnNetJobStateChange OnNetSuiteStateChange OnNetTaskStateChange OnNetVarChange Desciption Occurs when a job's state changes. Occurs when the Network Suite's state changes. Occurs when a task's state changes. Occurs when the value of a Network Suite variable changes.
Test Engine Events Name OnStartTest OnStopTest Description Occurs when a TestComplete test starts. Occurs when a test is over.
Web Testing Events Name OnWebBeforeNavigate Description Occurs before the browser navigates to the specified web page
Event Handling
175
OnWebDownloadStarted
OnWebDownloadComplete Occurs when the download of a web page has completed, failed or halted. OnWebPageDownloaded Occurs after the browser loads the specified page (or frame) OnWebQuit Occurs before the browser closes.
15.2.1 OnLogError
One of the most commonly used events, OnLogError can be used to gather addition information about the state of the system when the error occurred. For example: 1. Expand the "Events" Project Item. 2. Double click the "GeneralEvents" Project Item. 3. Add an "OnLogError" handler to your project by clicking the new button next to the OnLogError event .
4. Click the OK button in the "New Routine" dialog. TestComplete will create a new routine for you with two parameters: "Sender," which represents the event handler controller and "LogParams," which contains information on the message just about to be posted to the TestComplete log file. Note: If you set LogParams.Locked = true, TestComplete will not post a message at all to the log. The following code will post a picture of the desktop to the test log along with a duplication of the error
176
message:
15.3
Unexpected Windows
An unexpected window is defined by TestComplete as a modal dialog (a window that wants all keyboard and mouse activity for the application) that opens up over the application under test AND TestComplete is trying to interact with one of the other windows of the application under test. TestComplete has default handling for an unexpected window if "Ignore unexpected window" is not checked:
Event Handling
177
15.4
7. Close the application and stop the recording. 8. Comment out the code for the setting the value of the "numericUpDown2" control. 9. Run the created script. Example Script:
[VBScript] Sub Test1
178
Dim w1 Dim w2 TestedApps.UnexpectedWindow.Run Set w1 = Sys.Process("UnexpectedWindow").UnexpectedWindow Set w2 = w1.WinFormsObject("numericUpDown1").WinFormsObject("UpDownEdit", "") Call w2.Click() Call w2.Keys("1[Tab]") 'Call w1.WinFormsObject("numericUpDown2").WinFormsObject("UpDownEdit", ""). Keys("1") w1.WinFormsObject("button1").ClickButton w1.Close End Sub
[JScript] function Test1() { var w1; var w2; TestedApps.UnexpectedWindow.Run(); w1 = Sys.Process("UnexpectedWindow").UnexpectedWindow; w2 = w1.WinFormsObject("numericUpDown1"); w2.Click(); w2.Keys("1[Tab]"); //w1.WinFormsObject("numericUpDown2").WinFormsObject("UpDownEdit", ""). Keys("1"); w1.WinFormsObject("button1").ClickButton(); w1.Close(); }
You will get an unexpected window. This unexpected window contains additional information that the developer can use to track down the issue. So, we will create a event handler for the unexpected window that will retrieve this information.
Event Handling
179
10.Expand the Events Project Item. 11.Double-click the GeneralEvents Project Item.
12.Click the new Button next to the OnUnexpectedWindow event in the GeneralEvents Editor.
180
13.Click the OK button. 14.In the event add the following code:
[VBScript] Sub GeneralEvents_OnUnexpectedWindow(Sender, Window, LogParams) Call Log.Message("Additional Error Information", _ Window.WinFormsObject("TextBox", "").Text) End Sub
[JScript] function GeneralEvents_OnUnexpectedWindow(Sender, Window, LogParams) { Log.Message("Additional Error Information", Window.WinFormsObject("TextBox", "").Text); }
Event Handling
181
15.5
Summary
In this section, we have learned about events and the types of events that TestComplete provides. We have also learned how to attach script code to events. During this time, we learned about one of the most important events caused by unexpected windows and different options for handling unexpected windows.
Part
XVI
Working with Databases
183
16
16.1
16.2
ADO
ADO stands for "ActiveX Data Object". ADO allows TestComplete to access and manipulate data in a variety of data source (mostly databases). TestComplete offers two implementations to access ADO datasources. One route uses native Microsoft methods, the other through Borland (Codegear) methods. The table below shows the available methods: Microsoft CreateCommand CreateConnection Borland CreateADOCommand CreateADOConnection CreateADODataSet CreateADOQuery CreateADOStoredProc CreateADOTable The following Borland methods are specialized extensions of CreateADOCommand: CreateADODataSet, CreateADOQuery, CreateADOStoredProc, CreateADOTable. One of the hardest parts to using ADO is getting the connection string correct. You can get this information from the developer of the project you're testing, or look at http://www.connectionstrings.com.
Caution: TestComplete can not use the .NET-only connection string (for example the SqlConnection for SQL Server 2005).
184
1. Create an Connection to the database. 2. Open the Connection. 3. Create an Query Command. 4. Execute the Query Command. 5. Do something with the returned RecordSet. 6. Close the Connection. The following example uses the AdventureWorkDB (http://www.codeplex.com/MSFTDBProdSamples/ Release/ProjectReleases.aspx?ReleaseId=4004) and SQL Server 2005. The example reads through the Sales table, logging a customer and account number for each record.
[VBScript] Sub Main ' Create a new Connection object Set AConnection = ADO.CreateConnection ' Note that you can also create an ADO connection using the following code: ' Set AConnection = CreateObject("ADODB.Connection") ' Specify the connection string AConnection.ConnectionString = _ "Provider=SQLOLEDB.1;Integrated Security=SSPI;" & _ "Persist Security Info=False;" & _ "Initial Catalog=AdventureWorks;Data Source=.\SQLExpress" ' Activate the connection AConnection.Open ' Create a new Command object Set Cmd = ADO.CreateCommand ' To create an ADO command you can also use the following code: ' Set Cmd = CreateObject("ADODB.Command") ' Specify the connection Cmd.ActiveConnection = AConnection ' Specify command type and text Cmd.CommandText = _ "SELECT CustomerID, TerritoryID, AccountNumber, CustomerType," & _ " rowguid, ModifiedDate FROM Sales.Customer WHERE (CustomerType = ?)" Cmd.CommandType = adCmdText ' Create a new parameter Set Prm = Cmd.CreateParameter("@CustType",DB.adVarChar, DB.adParamInput) ' Specify the parameter value Prm.Size= 1 Prm.Value = "S" Cmd.Parameters.Append(Prm) ' Execute the command Set RecSet = Cmd.Execute ' Execute the command RecSet.MoveFirst While Not RecSet.EOF Log.Message(RecSet("CustomerID").Value & " has account " & _ RecSet("AccountNumber").Value) RecSet.MoveNext WEnd AConnection.Close End Sub
185
[JScript] function Main() { try { var AConnection, RecSet, Cmd, Prm; // Create a new Connection object AConnection = ADO.CreateConnection(); // Note that you can also create an ADO connection using the following code: // AConnection = new ActiveXObject("ADODB.Connection"); // Specify the connection string AConnection.ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;" + "Persist Security Info=False;" + "Initial Catalog=AdventureWorks;Data Source=.\\SQLExpress"; // Activate the connection AConnection.Open(); // Create a new Command object Cmd = ADO.CreateCommand(); // To create an ADO command you can also use the following code: // Cmd = new ActiveXObject("ADODB.Command"); // Specify the connection Cmd.ActiveConnection = AConnection; // Specify command type and text Cmd.CommandType = adCmdText; Cmd.CommandText = "SELECT CustomerID, TerritoryID, AccountNumber, CustomerType," + " rowguid, ModifiedDate FROM Sales.Customer WHERE (CustomerType = ?)" // Create a new parameter Prm = Cmd.CreateParameter("@CustType",DB.adVarChar, DB.adParamInput); // Specify the parameter value Prm.Size = 1; Prm.Value = "S"; Cmd.Parameters.Append(Prm); // Execute the command RecSet = Cmd.Execute(); // Process the results RecSet.MoveFirst(); while (! RecSet.EOF ) { Log.Message(RecSet("CustomerID").Value + " has account " + RecSet("AccountNumber").Value) RecSet.MoveNext(); } AConnection.Close(); } catch(exception) { Log.Error("Exception", exception.description); } }
For more information on ADO see Microsoft web site (http://msdn2.microsoft.com/en-us/library/ms675532 (VS.85).aspx)
186
16.3
In the example we will build the code step-by-step, adding the following features as we go: Connect to the ADO datasource. Create an ADO command. Create a parameter for the ADO command. The parameter will contain the customer number. Execute the command and get a result set. Iterate the result set, calculate the total sales and log the amount. 1. Create an ADO connection to the server, run the script to make sure the connection string is correct.
[VBScript] Sub Main ' Create a new Connection object Set AConnection = ADO.CreateConnection ' Note that you can also create an ADO connection using the following code: ' Set AConnection = CreateObject("ADODB.Connection") ' Specify the connection string AConnection.ConnectionString = _ "Provider=SQLOLEDB.1;Integrated Security=SSPI;" & "Persist Security Info=False;" & _ "Initial Catalog=AdventureWorks;Data Source=.\SQLExpress" ' Activate the connection AConnection.Open AConnection.Close End Sub
[JScript] function Main() { try { var AConnection, RecSet, Cmd, Prm; // Create a new Connection object AConnection = ADO.CreateConnection(); // Note that you can also create an ADO connection using the following code: // AConnection = new ActiveXObject("ADODB.Connection"); // Specify the connection string AConnection.ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;" + "Persist Security Info=False;" +
187
"Initial Catalog=AdventureWorks;Data Source=.\\SQLExpress"; // Activate the connection AConnection.Open(); AConnection.Close(); } catch(exception) { Log.Error("Exception", exception.description); } }
[JScript] function Main() { try { var AConnection, RecSet, Cmd, Prm; // Create a new Connection object AConnection = ADO.CreateConnection(); // Note that you can also create an ADO connection using the following code: // AConnection = new ActiveXObject("ADODB.Connection"); // Specify the connection string
188
AConnection.ConnectionString = _ "Provider=SQLOLEDB.1;Integrated Security=SSPI;" + "Persist Security Info=False;" + "Initial Catalog=AdventureWorks;Data Source=.\\SQLExpress"; // Activate the connection AConnection.Open(); // Create a new Command object Cmd = ADO.CreateCommand(); // To create an ADO command you can also use the following code: // Cmd = new ActiveXObject("ADODB.Command"); // Specify the connection Cmd.ActiveConnection = AConnection; // Specify command type and text Cmd.CommandType = adCmdText; Cmd.CommandText = "SELECT * FROM Sales.SalesOrderDetail AS d INNER JOIN " + "Sales.SalesOrderHeader AS h ON d.SalesOrderID = h.SalesOrderID" + " WHERE (h.CustomerID = ?)" AConnection.Close(); } catch(exception) { Log.Error("Exception", exception.description); } }
189
End Sub
[JScript] function Main() { try { var AConnection, RecSet, Cmd, Prm; // Create a new Connection object AConnection = ADO.CreateConnection(); // Note that you can also create an ADO connection using the following code: // AConnection = new ActiveXObject("ADODB.Connection"); // Specify the connection string AConnection.ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;" + "Persist Security Info=False;" + "Initial Catalog=AdventureWorks;Data Source=.\\SQLExpress"; // Activate the connection AConnection.Open(); // Create a new Command object Cmd = ADO.CreateCommand(); // To create an ADO command you can also use the following code: // Cmd = new ActiveXObject("ADODB.Command"); // Specify the connection Cmd.ActiveConnection = AConnection; // Specify command type and text Cmd.CommandType = adCmdText; Cmd.CommandText = "SELECT * FROM Sales.SalesOrderDetail AS d INNER JOIN " + "Sales.SalesOrderHeader AS h ON d.SalesOrderID = h.SalesOrderID" + " WHERE (h.CustomerID = ?)" // Create a new parameter Prm = Cmd.CreateParameter("@CustID",DB.adInteger, DB.adParamInput); // Specify the parameter value Prm.Size = 4; Prm.Value = 676; AConnection.Close(); } catch(exception) { Log.Error("Exception", exception.description); } }
190
AConnection.ConnectionString = _ "Provider=SQLOLEDB.1;Integrated Security=SSPI;" & _ "Persist Security Info=False;" & _ "Initial Catalog=AdventureWorks;Data Source=.\SQLExpress" ' Activate the connection AConnection.Open ' Create a new Command object Set Cmd = ADO.CreateCommand ' To create an ADO command you can also use the following code: ' Set Cmd = CreateObject("ADODB.Command") ' Specify the connection Cmd.ActiveConnection = AConnection ' Specify command type and text Cmd.CommandText = _ "SELECT * FROM Sales.SalesOrderDetail AS d INNER JOIN " & _ ":Sales.SalesOrderHeader AS h ON d.SalesOrderID = h.SalesOrderID " & _ " WHERE (h.CustomerID = ?)" Cmd.CommandType = adCmdText ' Create a new parameter Set Prm = Cmd.CreateParameter("@CustID",DB.adInteger, DB.adParamInput) ' Specify the parameter value Prm.Size= 4 Prm.Value = 676 Cmd.Parameters.Append(Prm) AConnection.Close End Sub
[JScript] function Main() { try { var AConnection, RecSet, Cmd, Prm; // Create a new Connection object AConnection = ADO.CreateConnection(); // Note that you can also create an ADO connection using the following code: // AConnection = new ActiveXObject("ADODB.Connection"); // Specify the connection string AConnection.ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;" + "Persist Security Info=False;" + "Initial Catalog=AdventureWorks;Data Source=.\\SQLExpress"; // Activate the connection AConnection.Open(); // Create a new Command object Cmd = ADO.CreateCommand(); // To create an ADO command you can also use the following code: // Cmd = new ActiveXObject("ADODB.Command"); // Specify the connection Cmd.ActiveConnection = AConnection; // Specify command type and text Cmd.CommandType = adCmdText; Cmd.CommandText = "SELECT * FROM Sales.SalesOrderDetail AS d INNER JOIN " + "Sales.SalesOrderHeader AS h ON d.SalesOrderID = h.SalesOrderID" + " WHERE (h.CustomerID = ?)"
191
// Create a new parameter Prm = Cmd.CreateParameter("@CustID",DB.adInteger, DB.adParamInput); // Specify the parameter value Prm.Size = 4; Prm.Value = 676; Cmd.Parameters.Append(Prm); AConnection.Close(); } catch(exception) { Log.Error("Exception", exception.description); } }
192
try { var AConnection, RecSet, Cmd, Prm; // Create a new Connection object AConnection = ADO.CreateConnection(); // Note that you can also create an ADO connection using the following code: // AConnection = new ActiveXObject("ADODB.Connection"); // Specify the connection string AConnection.ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;" + "Persist Security Info=False;" + "Initial Catalog=AdventureWorks;Data Source=.\\SQLExpress"; // Activate the connection AConnection.Open(); // Create a new Command object Cmd = ADO.CreateCommand(); // To create an ADO command you can also use the following code: // Cmd = new ActiveXObject("ADODB.Command"); // Specify the connection Cmd.ActiveConnection = AConnection; // Specify command type and text Cmd.CommandType = adCmdText; Cmd.CommandText = "SELECT * FROM Sales.SalesOrderDetail AS d INNER JOIN " + "Sales.SalesOrderHeader AS h ON d.SalesOrderID = h.SalesOrderID" + " WHERE (h.CustomerID = ?)" // Create a new parameter Prm = Cmd.CreateParameter("@CustID",DB.adInteger, DB.adParamInput); // Specify the parameter value Prm.Size = 4; Prm.Value = 676; Cmd.Parameters.Append(Prm); // Execute the command RecSet = Cmd.Execute(); AConnection.Close(); } catch(exception) { Log.Error("Exception", exception.description); } }
6. Iterate through the result set to total the orders (this could have been done with a single sql query).
[VBScript] Sub Main ' Create a new Connection object Set AConnection = ADO.CreateConnection ' Note that you can also create an ADO connection using the following code: ' Set AConnection = CreateObject("ADODB.Connection") ' Specify the connection string AConnection.ConnectionString = _ "Provider=SQLOLEDB.1;Integrated Security=SSPI;" & _ "Persist Security Info=False;" & _ "Initial Catalog=AdventureWorks;Data Source=.\SQLExpress" ' Activate the connection AConnection.Open ' Create a new Command object
193
Set Cmd = ADO.CreateCommand ' To create an ADO command you can also use the following code: ' Set Cmd = CreateObject("ADODB.Command") ' Specify the connection Cmd.ActiveConnection = AConnection ' Specify command type and text Cmd.CommandText = _ "SELECT * FROM Sales.SalesOrderDetail AS d INNER JOIN " & _ "Sales.SalesOrderHeader AS h ON d.SalesOrderID" & _ " = h.SalesOrderID WHERE (h.CustomerID = ?)" Cmd.CommandType = adCmdText ' Create a new parameter Set Prm = Cmd.CreateParameter("@CustID",DB.adInteger, DB.adParamInput) ' Specify the parameter value Prm.Size= 4 Prm.Value = 676 Cmd.Parameters.Append(Prm) ' Execute the command Set RecSet = Cmd.Execute ' Execute the command Dim Sales Sales = 0 While Not RecSet.EOF Sales = Sales + VarToFloat(RecSet("LineTotal").Value) RecSet.MoveNext WEnd Log.Message("Total Sales = " ^ Sales) AConnection.Close End Sub
[JScript] function Main() { try { var AConnection, RecSet, Cmd, Prm; // Create a new Connection object AConnection = ADO.CreateConnection(); // Note that you can also create an ADO connection using the following code: // AConnection = new ActiveXObject("ADODB.Connection"); // Specify the connection string AConnection.ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;" + "Persist Security Info=False;" + "Initial Catalog=AdventureWorks;Data Source=.\\SQLExpress"; // Activate the connection AConnection.Open(); // Create a new Command object Cmd = ADO.CreateCommand(); // To create an ADO command you can also use the following code: // Cmd = new ActiveXObject("ADODB.Command"); // Specify the connection Cmd.ActiveConnection = AConnection; // Specify command type and text Cmd.CommandType = adCmdText; Cmd.CommandText =
194
"SELECT * FROM Sales.SalesOrderDetail AS d INNER JOIN" + " Sales.SalesOrderHeader AS h ON d.SalesOrderID = h.SalesOrderID" + " WHERE (h.CustomerID = ?)" // Create a new parameter Prm = Cmd.CreateParameter("@CustID",DB.adInteger, DB.adParamInput); // Specify the parameter value Prm.Size = 4; Prm.Value = 676; Cmd.Parameters.Append(Prm); // Execute the command RecSet = Cmd.Execute(); var Sales; Sales = 0; while (! RecSet.EOF ) { Sales = Sales + RecSet("LineTotal").Value; RecSet.MoveNext(); } Log.Message("Total Sales = " + Sales); AConnection.Close(); AConnection.Close(); } catch(exception) { Log.Error("Exception", exception.description); } }
16.4
Summary
In this section we discussed options for connecting and manipulating datasources using ADO and BDE. You learned how to retrieve ADO data for use within your tests.
Part
XVII
Web Page Testing
196
17
17.1
17.2
197
17.3
Naming Conventions
The naming convention for HTML elements used by TestComplete depends on the web page model used: DOM - HTML elements are in the form of Item(index). The index will be either the ID or Name attribute, if any (with the Identification attribute having priority). If the element does not have either attribute, TestComplete will assign an index number based on the order the item was created. TAG - HTML elements have the same form as DOM but are sorted by type. Tree - HTML elements have the form ObjectType(Index), for example: Panel(0) - div element, Image ("Logo.gif") - image element.
17.4
198
...or the checkpoint drop down from on the Editor toolbar of TestComplete.
2. Selecting either option displays the Create Web Comparison Checkpoint dialog.
199
4. The extent of the comparison is controlled by the options below the "Page object" in the dialog. Compare entire page - The whole HTML page is saved and is compared. Compare only tab structure - Only tag names are compared, not attributes, attributes' values and elements' values. Compare only specified tags - Only the selected elements will be compared. o Links - Only A elements are compared (text and attributes of the element are compared as well). o Images - Only IMG elements are compared. o Input elements - Only INPUT elements are compared. o Read content from a server - Read content from the browser's window or the web server 5. Press the OK button and you will be presented with the Copy Text to Clipboard dialog. The dialog has the script code that will perform the web page comparison. Note: In this case the dialog contents will be placed into the clipboard so you can paste them into your script routine. If you do the comparison while recording, TestComplete puts the code in for you automatically.
200
Tip: If you have a web page that has dynamically created items, you can set a timeout for the web comparison to wait for the page to be populated before doing the comparison (default is the Autowait timeout).
17.5
201
2. Selecting either option will display the Create Web Accessibility Checkpoint dialog.
202
3. The types of accessibilities that TestComplete can check for are: Check "alt" attribute - All IMG, APPLET, AREA and INPUT elements must have a non-empty ALT attribute. Check "mailto:" - Web page must have at least one A element (link), whose HREF attribute starts with mailto: Check image sizes - All IMG elements must have the WIDTH and HEIGHT attributes specified. Check "title" tag - The web page must have a non-empty TITLE elment. Check tab indexes - All INPUT, SELECT, and TEXTAREA elements must have the TABINDEX attribute. Check link accessibility - Checks for broken links. Check ActiveX objects - Verifies there are no ActiveX objects on the web page. Check Applet object - Verifies there are no Applet objects on the web page. Check multimedia links - Verifies there are not AVI or SWF files on the web page. Check server-side images - Verifies that none of the IMG elements contain SRC attribute with parameters. 4. Press the OK button and TestComplete will present you with a dialog showing code for the Web Accessibility Checkpoint.
203
17.6
[VBScript] Sub NativeFind Dim PageObj Dim ProductLink Set PageObj = Sys.Process("iexplore"). Page("http://www.automatedqa.com/") Set ProductLink = PageObj.NativeWebObject.Find("title","Products","A") if ProductLink.Exists Then ProductLink.Click End If End Sub
204
[JScript] function NativeFind() { var PageObj var ProductLink PageObj = Sys.Process("iexplore").Page("http://www.automatedqa.com/") ProductLink = PageObj.NativeWebObject.Find("title","Products","A") if (ProductLink.Exists) ProductLink.Click() }
The second method to find objects on a web (or any other application), is to use the TestedObject.Find() method. This method allows you to use multiple properties and values to select a web element. The example below uses the page object again, not the TestedObject. In this case the page object is the TestedObject, TestedObject can be any on-screen object. To perform the same search as above:
[VBScript] Sub TestedObjFind Dim PropArray, ValuesArray Dim PageObj Dim ProductLink ' Creates arrays of properties and values PropArray = CreateVariantArray(0, 1) ValuesArray = CreateVariantArray(0, 1) ' Specifies property names PropArray(0) = "title" PropArray(1) = "tagName" ' Specifies the property values ValuesArray(0) = "Products" ValuesArray(1) = "A" Set PageObj = Sys.Process("iexplore").Page("http://www.automatedqa.com/") Set ProductLink = PageObj.Find(PropArray,ValuesArray,3) if ProductLink.Exists Then ProductLink.Click End If End Sub
[JScript] function ConvertArray(AArray) { // Uses the Dictionary object to convert a JScript array var objDict = Sys.OleObject("Scripting.Dictionary"); objDict.RemoveAll(); for (var j in AArray) objDict.Add(j, AArray[j]); return objDict.Items(); } function TestedObjFind() {
205
var PropArray, ValuesArray, ConvertedPropArray, ConvertedValuesArray; var PageObj; var ProductLink; // Creates arrays of properties and values PropArray = new Array(2); ValuesArray = new Array(2); // Specifies property names PropArray[0] = "title"; PropArray[1] = "tagName"; // Specifies the property values ValuesArray[0] = "Products"; ValuesArray[1] = "A"; // Converts arrays ConvertedPropArray = ConvertArray(PropArray); ConvertedValuesArray = ConvertArray(ValuesArray); PageObj = Sys.Process("iexplore").Page("http://www.automatedqa.com/") ProductLink = PageObj.Find(ConvertedPropArray,ConvertedValuesArray,3) if (ProductLink.Exists) ProductLink.Click() }
Note: Notice that the Find() method passes a depth value of 3. The depth value indicates that at most, TestComplete will search the object tree three levels below the current selected TestedObject. Choosing the method to use depends on how far down the object tree you are and how complex a search you require. If you are using the page object, NativeWebObject.Find() is the fastest. Below the page object, it will depend on the current depth and how far down you need to search. For more complex searches, TestedObject.Find() provides more flexibility.
17.7
Dynamic HTML
Script recording in TestComplete does not record mouse movements, only mouse click and keyboard entry. The lack of mouse movement information can present a problem in dealing with dynamic HTML elements such a Hover Menus which require the mouse to hover (move over) the menu to active. For example the web page http://www.asp.net/AJAX/AjaxControlToolkit/Samples/HoverMenu/HoverMenu.aspx has a hover menu attached to the word "Have project idea". If you were to attempt recording interaction with this menu, the playback would fail as the menu would not be visible to click on. This can be solved by using the HoverMouse method in the script. To get the HoverMouse method in the record you can do the following: Note: This example may vary depending on your OS version (Vista or XP) as well as your browser version. For Vista you must run Internet Explorer with administrator privledges. You can refer to the Hands On Lab for this chapter to set this up. 1. Start Internet Explorer 2. Browse to http://www.asp.net/AJAX/AjaxControlToolkit/Samples/HoverMenu/HoverMenu.aspx
206
3. Hover the mouse over the first row until the popup menu appears then click the Edit link.
[JScript - Recorded Code] function Test1() { var page; page = Aliases.iexplore.pageHovermenuSample; page.ToURL( "http://www.asp.net/AJAX/AjaxControlToolkit/Samples/HoverMenu/HoverMenu.aspx"); page.formAspnetform.panelMasterPage.panelMasterContent .panelMasterContentplaceholder.panelDemoarea.panelCtl00SamplecontentUp1.panel .tableCtl00SamplecontentGridview1.cell.panelCtl00SamplecontentGridview11 .panel.panel.linkCtl00SamplecontentGridview1C.Click(); }
At this point, if we playback this recording it will fail as the popup menu will not be on screen. We need to use the HoverMouse method on an object within the first row to allow the popup menu time to appear. 1. Use the Object Browser to locate a textnode within the first row of the grid (you can use the Object Properties window and its Finder tool to make this easier)
207
2. With the information pertaining to this text node we can modify our code to call the HoverMouse method allowing the popup menu to appear on screen.
[VBScript - Modified Code] Sub Test1 Dim page Dim cell Dim textNode Set page = Aliases.iexplore.pageHovermenuSample Call page.ToURL( "http://www.asp.net/AJAX/AjaxControlToolkit/Samples/HoverMenu/HoverMenu.aspx") ' Code to hover the mouse over the text of the first cell of the table Set cell = page.formAspnetform.panelMasterPage.panelMasterContent .panelMasterContentplaceholder.panelDemoarea.panelCtl00SamplecontentUp1 .panel.tableCtl00SamplecontentGridview1.cell Set textNode = cell.panelCtl00SamplecontentGridview1.table.cell .textnodeCtl00SamplecontentGridvi Call textNode.HoverMouse(5, 5) Call cell.panelCtl00SamplecontentGridview11.panel.panel .linkCtl00SamplecontentGridview1C.Click() End Sub
208
{ var page; var cell; var textNode; page = Aliases.iexplore.pageHovermenuSample; page.ToURL( "http://www.asp.net/AJAX/AjaxControlToolkit/Samples/HoverMenu/HoverMenu.aspx"); // Code to hover the mouse over the text of the first cell of the table cell = page.formAspnetform.panelMasterPage.panelMasterContent .panelMasterContentplaceholder.panelDemoarea.panelCtl00SamplecontentUp1.panel .tableCtl00SamplecontentGridview1.cell; textNode = cell.panelCtl00SamplecontentGridview1.table.cell .textnodeCtl00SamplecontentGridvi; textNode.HoverMouse(5, 5); cell.panelCtl00SamplecontentGridview11.panel.panel .linkCtl00SamplecontentGridview1C.Click(); }
The code above will now hover the mouse over the first row of the grid allowing the popup menu to appear and thus allowing the click to work.
17.8
209
5. Press the recording button in the test engine toolbar. 6. Click the run application button in the recording toolbar to start Internet Explorer 7. Type "Falafel Software" (without the quotes) into the Google Search box 8. Click the Google Search button 9. Stop the recording (Your code may not exactly match the example below).
Sub Test1 Dim iexplore Dim page Dim form TestedApps.iexplore.Run Set iexplore = Aliases.iexplore Set page = iexplore.pageGoogle Call page.ToURL("http://www.google.com/") Set form = page.formF Call form.table.cell.textboxQ.Keys("falafel software") form.tableGacM.cell.panelGacBt.buttonGoogleSearch.Click 'Please wait until download completes: "http://www.google.com/search?hl=en&q=falafel+software&aq=f&oq=&aqi=g1" iexplore.pageFalafelSoftwareGoogleSearch.Wait End Sub
[Jscript]
210
function Test1() { var iexplore; var page; var form; TestedApps.iexplore.Run(); iexplore = Aliases.iexplore; page = iexplore.pageGoogle; page.ToURL("http://www.google.com/"); form = page.formF; form.table.cell.textboxQ.Keys("falafel software"); form.tableGacM.cell.panelGacBt.buttonGoogleSearch.Click(); //Please wait until download completes: "http://www.google.com/search?hl=en&q=falafel+software&aq=f&oq=&aqi=g1" iexplore.pageFalafelSoftwareGoogleSearch.Wait(); }
10. Close the Tested Application 11. Run the recorded test.
[VBScript] Sub FindTest Dim iexplore Dim page Dim form TestedApps.iexplore.Run Set iexplore = Aliases.iexplore Set page = iexplore.pageGoogle Call page.ToURL("http://www.google.com/") Set form = page.formF
211
Call form.table.cell.textboxQ.Keys("falafel software") form.tableGacM.cell.panelGacBt.buttonGoogleSearch.Click 'Please wait until download completes: "http://www.google.com/search?hl=en&q=falafel+software&aq=f&oq=&aqi=g1" iexplore.pageFalafelSoftwareGoogleSearch.Wait Dim PropArray, ValuesArray ' Creates arrays of properties and values PropArray = CreateVariantArray(0, 1) ValuesArray = CreateVariantArray(0, 1) ' Specifies property names PropArray(0) = "tagName" PropArray(1) = "innerText" ' Specifies the property values ValuesArray(0) = "A" ValuesArray(1) = "Falafel Software*" iexplore.pageFalafelSoftwareGoogleSearch.Refresh iexplore.pageFalafelSoftwareGoogleSearch.Find(PropArray,ValuesArray,100).Click End Sub
[JScript] function ConvertArray(AArray) { // Uses the Dictionary object to convert a JScript array var objDict = Sys.OleObject("Scripting.Dictionary"); objDict.RemoveAll(); for (var j in AArray) objDict.Add(j, AArray[j]); return objDict.Items(); } function FindTest() { var iexplore; var page; var form; TestedApps.iexplore.Run(); iexplore = Aliases.iexplore; page = iexplore.pageGoogle; page.ToURL("http://www.google.com/"); form = page.formF; form.table.cell.textboxQ.Keys("falafel software"); form.tableGacM.cell.panelGacBt.buttonGoogleSearch.Click(); //Please wait until download completes: "http://www.google.com/search?hl=en&q=falafel+software&aq=f&oq=&aqi=g1" iexplore.pageFalafelSoftwareGoogleSearch.Wait(); // New Stuff below var PropArray, ValuesArray, ConvertedPropArray, ConvertedValuesArray; // Creates arrays of properties and values PropArray = new Array(2); ValuesArray = new Array(2); // Specifies property names PropArray[0] = "tagName";
212
PropArray[1] = "innerText"; // Specifies the property values ValuesArray[0] = "A"; ValuesArray[1] = "Falafel Software*"; // Converts arrays ConvertedPropArray = ConvertArray(PropArray); ConvertedValuesArray = ConvertArray(ValuesArray); iexplore.pageFalafelSoftwareGoogleSearch.Refresh(); iexplore.pageFalafelSoftwareGoogleSearch .Find(ConvertedPropArray,ConvertedValuesArray,100).Click(); }
17.9
Summary
In this section we learned about web page testing, how TestComplete represents web pages in the Object Browser and how to switch between them. In addition, we learned about the different types of web checkpoints TestComplete has, and how to use them. The Find methods made it easier for us to deal with unnamed web elements and the HoverMouse method made it so we could test dynamic HTML elements.
Part
XVIII
WebServices Testing
214
18
18.1
WebServices Testing
Objectives
This section demonstrates how to test a web service. In this section you'll learn: Importing Web Services into TestComplete. Calling Simple Methods of Web Services in TestComplete. Creating Web Service Types (objects) in TestComplete. Calling Complex Method of Web Services. Creating a Web Service Checkpoint.
18.2
WebServices Testing
215
e. Click the OK button A list of types and methods that are available for the selected Web service is displayed.
216
WebServices Testing
217
Using the TestComplete AutoCompletion feature you can import the example Web Service supplied with the book. The previous example above can be generated using AutoCompletion: 1. Type Log.m in the code editor. 2. Press the "[Enter]" key. 3. Move the cursor between the parenthesis. 4. Type W[Enter]. 5. Select the Web Service from the code completion (MyWebServiceName). 6. Type .. 7. Select the HelloWorld method from the code completion.
[JScript] function User() { var Result; var TypeFactory; //Get the type factory for the web service TypeFactory = WebServices.SimpleProjectTracker.TypeFactory; Result = TypeFactory.User; return Result; }
[VBScript] Function User Dim TypeFactory 'Get the type factory for the web service Set TypeFactory = WebServices.SimpleProjectTracker.TypeFactory Set User = TypeFactory.User End Function
This code creates the User object for use with the Web Service (such as invoking the AddNewUser method). To access the code generator: 1. Expand the list of types in your web service. 2. Select the type desired. 3. Click the Code button at the end of the line with the type.
218
5. Paste the generated code into the script editor using either "<ctrl>-V" or the Edit | Paste menu option. Now that we have the method to create a User, we can use this method to add a new user to the database using the Web service. The method we are calling in the Web service is AddNewUser().
[JScript] function AddAUser() { var aUser; aUser = User(); aUser.Name = "Test"; aUser.Email = "test@test.com"; Log.Message("New User Id is " + WebServices.SimpleProjectTracker.AddNewUser(aUser)); } Copyright 2009 AutomatedQA Corp. - 2.0 Release
WebServices Testing
219
[VBScript] Sub AddAUser Dim aUser Set aUser = User() aUser.Name = "Test" aUser.Email = "test@test.com" Log.Message("New User Id is " & WebServices.SimpleProjectTracker.AddNewUser(aUser)) End Sub
18.3
WebServices Checkpoint
You can perform all of the operations needed to call a web services method and check the results yourself, or you can use the Create Web Service Checkpoint Wizard to walk you through the process. In general, performing the operations by hand is more flexible, but the wizard helps you create the checkpoints faster and more conveniently, which is important if you are new to TestComplete. The wizard helps you perform the following actions: Create an XMLCheckpoint project item that stores a baseline copy of a web services response. Generate script code that calls the web services method and checks the result. You can invoke the wizard when recording a test or at design time: To display the wizard when recording a test, select toolbar: Create Web Service Checkpoint from the Recording
To display the wizard at design time, select the Create Web Service Checkpoint from the Tools toolbar. If this toolbar is hidden, right-click somewhere in the toolbar area and select Tools from the ensuing context menu:
220
In the wizard, the following actions will take place: Selecting the desired web service. Selecting the method to be called. Specifying the method parameters. Specifying the expected result. 1. Invoke the wizard. On the "Select Web Service" page of the wizard, select the Web Service project item that corresponds to the tested web service.
2. On the "Select Web Service Method" page of the wizard, choose the web service method to be called.
WebServices Testing
221
3. On the "Specify Method Parameters" page, enter the method parameter values. If the parameters have a simple value type (a string, integer, Boolean and so on), enter its value directly on the page.
Note: To specify complex parameter values (that refer to objects), invoke the special "Complex Parameter" dialog.
222
4. On the "Store Expected Response" page of the wizard, specify the XMLCheckpoint project item that will store the expected response of the web service method.
WebServices Testing
223
The response can be saved to a new or to an existing XMLCheckpoint project item. When creating a new project item, remember that TestComplete will use the project items name to address this project item from scripts. So, the name must be a valid script identifier. Scripting languages supported by TestComplete use different naming rules. To specify a name that will conform to the rules of any language, enter a string that starts with a letter and that only contains letters, digits and underscore symbols. TestComplete automatically generates the expected response of a method call. By default, TestComplete uses predefined values for XML document elements that correspond to the result value (or values). For instance, if the method returns an integer value, then TestComplete generates the 0 value for the element that holds the result value. You should replace this pre-defined value with the expected value. Else, the comparison will be meaningless. 5. Press "Finish" to close the wizard. TestComplete automatically creates (or updates) the specified XMLCheckpoint project item and then generates script code that calls the method and compares the result with the data stored by the project item.
224
If the checkpoint was created during recording, TestComplete displays the generated code in the Add Text to Script dialog. Using this dialog you can insert the generated script instructions into the recorded code. If the checkpoint was created at design time, TestComplete displays the Copy Text to Clipboard dialog. Here, the generated code can be copied to the clipboard and then pasted into the script code.
[VBScript] Call WebServices.SimpleProjectTracker.AddNewProject(XML.project) If (Not XML.AddNewProject.Compare(WebServices.SimpleProjectTracker)) Then Call Log.Error("The AddNewProject method of the SimpleProjectTracker web" _ " service returned an incorrect value.") End If
[JScript] WebServices.SimpleProjectTracker.AddNewProject(XML.project); if(!XML.AddNewProject.Compare(WebServices.SimpleProjectTracker)) Log.Error("The AddNewProject method of the SimpleProjectTracker web" + " service returned an incorrect value.");
18.4
WebServices Testing
225
226
18.5
XML Checkpoint
The XML checkpoint is used to compare two different XML documents (such as the response from a Web Service method call). TestComplete stores the XML checkpoint information under the "Stores | XML " project item folder.
TestComplete compares two XML documents by moving down the hierarchy of document elements and comparing each document node. The comparison starts at the root node for each document. The following steps are performed for each node: Finds the "matching" node from each document and compares each of the node values. Nodes are matched on the baseName, namespaceURI properties as well as node prefix and type. Compares node attributes and namespace declarations. Gets a list of child nodes and performs a comparison. If the node or any of the child nodes are different, TestComplete will report the differences.
WebServices Testing
227
By configuring the checkpoint options of an XML checkpoint, the default behavior of the comparison can be changed.
The checkpoint options are: Ignore node order - TestComplete does not check if the node was found in the same place in both
228
documents. Ignore attributes - TestComplete only compares names and values for the XML elements. Ignore namespace declarations - TestComplete does not check the namespace attribute of the XML nodes. Ignore prefixes - TestComplete does not check the prefix on the name of the XML node. Compare in subtree mode - The comparison results will not include nodes that only exist in the actual document and not in the stored (expected) document (Good for checking only part of an XML document).
18.6
WebServices Testing
229
7. Click the "Get Services" button. 8. Select the SimpleProjectTrackerWS (SOAP 1.2) as the tested service. 9. Click the "OK" button. 10.Create a new method in the script editor. Call the method "GetTask". 11.Create a variable for your scripting language. Call the variable "ReturnValue". 12.Assign the value to the results of "WebServices.TrainingWS.GetTaskByID(1) ". Caution: This result is actually a complex value (object) so be careful with the assignment (use SET for VBScript). 13.Add a line to Log the value of "ReturnValue.Name"
[VBScript] Sub GetTask Dim ReturnValue Set ReturnValue = WebServices.TrainingWS.GetTaskByID(1) Log.Message("Task 1 is " & ReturnValue.Name) End Sub
[JScript] function GetTask() { var ReturnValue; ReturnValue = WebServices.TrainingWS.GetTaskByID(1); Log.Message("Task 1 is " + ReturnValue.Name); }
14.Right-click inside the method just created and select Run Current Routine.
230
[VBScript] Function ProjectType Dim TypeFactory 'Get the type factory for the web service Set TypeFactory = WebServices.TrainingWS.TypeFactory Set ProjectType = TypeFactory.Project End Function Sub AddProject Dim Prj
WebServices Testing
231
Set Prj = ProjectType Prj.Name = "TestComplete Training Lab" Prj.Manager = 1 Prj.DueDate = Date() + 7 Dim ReturnValue ReturnValue = WebServices.TrainingWS.AddNewProject(Prj) Log.Message("New Project Id is " & ReturnValue) End Sub
[JScript] function ProjectType() { var Result; var TypeFactory; //Get the type factory for the web service TypeFactory = WebServices.TrainingWS.TypeFactory; Result = TypeFactory.Project; return Result; } function AddProject() { var Prj; Prj = ProjectType(); Prj.Name = "TestComplete Training Lab" Prj.Manager = 1; Prj.DueDate = Utilities.Date() + 7; var ReturnValue; ReturnValue = WebServices.TrainingWS.AddNewProject(Prj); Log.Message("New Project Id is " + ReturnValue); }
17.Right Click inside the method just created and select "Run Current Routine"
2. Select the TrainingWS Web Service and click the Next button. 3. Select the GetProjectByID method from the list. 4. Set the 'id' parameter value to 1 and click the Next button. 5. Set the values on the node to match the values shown in the image below inside the soap:Body area only.
232
6. Click the Finish button. 7. Click the Copy button of the Copy Text to Clipboard dialog. 8. Create a new method in the script edited called "Checkpoint1".
Copyright 2009 AutomatedQA Corp. - 2.0 Release
WebServices Testing
233
[VBScript] Sub CheckPoint1 Call WebServices.TrainingWS.GetProjectByID(1) If (Not XML.GetProjectByID.Compare(WebServices.TrainingWS)) Then Call Log.Error(_ "The GetProjectByID method of the TrainingWS web service returned an"_ " incorrect value.") End If End Sub
[JScript] function CheckPoint1() { WebServices.TrainingWS.GetProjectByID(1); if(!XML.GetProjectByID.Compare(WebServices.TrainingWS)) Log.Error( "The GetProjectByID method of the TrainingWS web service returned an incorrect"+ "value."); }
11.An error message is displayed in the test log. Expand the details of the XML node in the test log to see the errors.
234
12.Double-click the "GetProjectByID" project item of the "Stores | XML" project item. 13.Expand the nodes until the Description and DueDate nodes are shown. 14.Delete the Description and DueDate nodes.
15.Check the "Compare in subtree mode" 16.Re-run the "Checkpoint1" Routine. No error will be displayed in the test log.
WebServices Testing
235
18.7
Summary
In the section we learned how to retrieve information about web services in order to perform web service testing. We started by testing with a simple web service method using primitive types and worked up to testing a web service with a complex interface. We also learned how to change the default behavior of TestComplete for timeouts and about XML checkpoints.
Part
XIX
HTTP Performance Testing
237
19
19.1
19.2
19.3
238
TestComplete can record both HTTP and HTTPS web traffic and automatically captures these protocols without any specific proxy setting requirements. Traffic Transponder Cookie handling - Configures how TestComplete handles sending of cookies during playback. See the cookie handling section below for more information. Send timeout - The number of seconds that TestComplete will wait for a acknowledgement from the web server that a connection has been made. Receive times - The number of seconds that TestComplete will wait for a reply from the web server. Simulate request to third-party site - If checked, TestComplete will not ask for images or other information from other sites that the web page might request. Store request details - If unchecked, TestComplete will only store the header information and not the details of a web request.
239
Synchronize requests - Forces the order of requests to remain the same as when recording, i.e. get the web page before the images on the page. Requests can get out of order if network traffic is high. HTML Hidden Controls Certain web pages, like ASP.NET, utilize hidden HTML controls to transfer information from server to client and back. TestComplete allows you to specify which hidden values should be updated during playback to better simulate interaction with the server. You can specify which controls TestComplete should update during playback by editing the HTTP Load Testing Project Item. Simply right click and select "Edit" (see Hidden Controls editor below). By default, TestComplete populates the list with common ASP.NET hidden field names though you can add any values necessary for your testing requirements.
19.4
Cookie Handling
A cookie is data stored on the client side, such as a user security token used to authorize an request to a secured web site. The type of cookies that a web site generates makes a difference in how a web server responds to a request. Cookie data can change from run to run of a load test and TestComplete allows different methods for handling cookies: Do not use cookies - This is the same as disabling cookies in your Internet browser. TestComplete will ignore all cookies while running the load test. Use recorded cookies - Cookies will affect the server response and the server should produce the same responses as recorded. However, since cookies can have expiration dates, the response may be an error. Use real-time cookies - The default selection, TestComplete will replace the cookies as needed from the web server responses. The default for a visually created test is to set the ClearCookies property of the virtual users to true. When the ClearCookies property is true, all cookies are automatically recreated. If you want cookies to be recreated, cookies need to be cleared before starting a load test for virtual users created in script.
19.5
Recording
Recording HTTP traffic is similar to standard recording. One difference - it is easier if you have your client application (Internet Explorer, Firefox, etc) started, and in the case of web browsers, on the web page you want to start on. Note: It is also a good idea to clear the cache of the web browser you are using before recording. Tip: If you are planning to modify the recorded HTTP traffic and using 'classic' ASP.NET (using viewstate), turn off HTTP 1.1 in the web browser before recording. This will prevent the web server
240
from using HTTP compression, but makes it easier to modify the traffic. 1. Start by clicking the record button in TestComplete. On the recording toolbar, click the "Record an HTTP task" button.
2. To select a load testing task either: Enter a name under Record a new task for a new task. Select Append traffic to the following task and select an existing task. This will add the http traffic to an existing task.
3. When the recording is done, you will end up with a script for running a load test with one single virtual user.
[VBScript] Sub Test1 Dim HTTPTask Dim VirtualUser Set HTTPTask = LoadTesting.HTTPTaskByName("Task") Set VirtualUser = LoadTesting.CreateVirtualUser("VirtualUser1") Set VirtualUser.Task = HTTPTask Call VirtualUser.Run("Task") End Sub
241
[JScript] function Test1() { var HTTPTask; var VirtualUser; HTTPTask = LoadTesting.HTTPTaskByName("Task"); VirtualUser = LoadTesting.CreateVirtualUser("VirtualUser1"); VirtualUser.Task = HTTPTask; VirtualUser.Run("Task"); }
4. The recorded task will be under the Tasks project item under the LoadTesting project item in the Project Explorer.
19.6
242
The request page holds the properties of the currently selected request in the Connections tree. The fields of the request header are shown in the table. All of these fields can be modified directly or in script code. The request method (POST or GET) is shown in the edit box above the fields (note: the protocol version is also shown). The "Raise Events" option is used to indicate this request will trigger an OnLoadTestingRequest event during playback. OnLoadTestingRequest will allow modification of the request before sending it to the web server.
The response page shows the properties and contents of the response from the web server for the selected request. Depending on the Content-Type, TestComplete will show the response content below the properties grid. For example, an image request will show the image, a SOAP request will show the SOAP response, etc. Again, the information can be edited here or changed in script code. The "Raise Events" checkmark will call the OnLoadTestingResponse for the selected request/response pair.
19.7
243
1. Select the "Tests" project item under the Load Testing project item
4. Enter a "Description" for the test 5. Enter or select a "Result Group". Result groups are used to categorize groups of test runs for analysis. 6. Right-click in the Virtual Users area and select New Item.
244
8. Enter the number of virtual user you want for this group (it is not recommend that more the 300 virtual users be assigned to a computer). 9. Choose which task this group of user is going to perform. 10.Assign the group to run on a particular computer (Master is the local computer). 11.Choose which browser to simulate in the request. 12.The start delay is how long after the test starts to kick off this group (simulating a gradual increase in load). 13.Change the connection speed to simulate the speed of the download. Once you are finished creating the test, you can run the test by right clicking and selecting Run.
19.8
The column headings are as follows: Virtual User # in the order they complete their task. Did the user complete the task without error/warnings. Virtual User Name. The task performed. Which station performed the task. The total time needed to complete the task. The number of connections simulated in the task. The middle section shows how each of the connections did for the currently selected user from the users section.
The green line in the graph shows the actual request execution sum, the red line show the total time to perform all requests. Column heading are: State (did this connection pass or fail).
245
Host that the connection was run against. Which port the connection used. How long it took to Initialize the connection. Number of requests in this connect. The total time to simulate this connection. Total Bytes received from the web server for this connection. Total Bytes sent to the web server for this connection. How long after the start of the load test was this request sent. How many bytes per a second where sent/received. The time of day the connection was started. How long it took to do the request. The minimum response time for all the requests in this connection The maximum response time for all the requests in this connection The bottom section is divided into two parts, Requests and Headers:
Requests columns are: Request # in the selected connection. The State of the request. The time to do the request. # of bytes sent. how long until a response. # of bytes received. # of bytes sent/received per a second. # of bytes sent per second. # of bytes received per a second. The Headers area shows the actual headers sent and received for the selected request.
246
Select the named group you are interested in and you will get the results of all the test runs for that group.
19.9
247
Set Request = HTTPTask.Connection(0).Request(0) Randomize Request.Variables.Item("paints") = Int(1000 * Rnd()) + 1 Request.Variables.Item("pencils") = Int(1000 * Rnd()) + 1 Request.Variables.Item("albums") = Int(1000 * Rnd()) + 1 Set VirtualUser = LoadTesting.CreateVirtualUser("VirtualUser1") Set VirtualUser.Task = HTTPTask Call VirtualUser.Run("Order") End Sub
[JScript] function Test1() { var HTTPTask var Request var VirtualUser HTTPTask = LoadTesting.HTTPTaskByName("Order") Request = HTTPTask.Connection(0).Request(0) Request.Variables.Item("paints") = Math.round(100 * Math.random()) + 1 Request.Variables.Item("pencils") = Math.round(100 * Math.random()) + 1 Request.Variables.Item("albums") = Math.round(100 * Math.random()) + 1 VirtualUser = LoadTesting.CreateVirtualUser("VirtualUser1") VirtualUser.Task = HTTPTask VirtualUser.Run("Order") }
Caution: There is one warning with this method, since you are making a copy of the HTTP task for each virtual user, it is possible to consume too much memory causing a slow down of the test.
The Second method is to use the OnLoadTestingRequest event to modify the traffic. To use OnLoadTestingRequest, first checkmark the raise events on all the request you wish to modify.
248
Set HTTPTask = LoadTesting.HTTPTaskByName("Task") HTTPTask.Connection(0).Request(0).RequestEventTrigger = True Set VirtualUser = LoadTesting.CreateVirtualUser("VirtualUser1") Set VirtualUser.Task = HTTPTask Call VirtualUser.Run("Task") End Sub
[JScript] function Test4() { var HTTPTask; var VirtualUser HTTPTask = LoadTesting.HTTPTaskByName("Order") HTTPTask.Connection(0).Request(0).RequestEventTrigger = true VirtualUser = LoadTesting.CreateVirtualUser("VirtualUser1"); VirtualUser.Task = HTTPTask; VirtualUser.Run("Task"); }
Next, add the OnLoadTestingRequest event handler. Open the editor for Events from the Project Explorer and click the New button next to the OnLoadTestingRequest in the HTTP LoadTesting Events category.
Click OK in the New Routine Dialog and add script code to modify the request:
[VBScript] Sub GeneralEvents_OnLoadTestingRequest(Sender, User, Request) Request.Variables.Item("paints") = Int(1000 * Rnd()) + 1 Request.Variables.Item("pencils") = Int(1000 * Rnd()) + 1 Request.Variables.Item("albums") = Int(1000 * Rnd()) + 1 End Sub
[JScript] function GeneralEvents_OnLoadTestingRequest(Sender, User, Request) { Request.Variables.Item("paints") = Math.round(100 * Math.random()) + 1 Request.Variables.Item("pencils") = Math.round(100 * Math.random()) + 1 Request.Variables.Item("albums") = Math.round(100 * Math.random()) + 1 }
249
2. Start up Internet Explorer and open the www.automatedqa.com web page. 3. Switch from recording a script to recording HTTP traffic.
4. Record an HTTP Load Test. Enter TestComplete in the search and hit the Enter key. Click the Contact Us link. Click the Home link. Stop the recording. 5. Double-click the newly created Task in the Project Explorer. 6. In the task editor, delete connections that do not point to www.automatedqa.com:
250
7. Right-click on the Tests Project Item of the LoadTesting Project Item in the Project Explorer and Select Add | New Item... 8. Press OK in the Create Project Item Dialog. 9. Create an HTTP Load Test with five virtual users. Add a description "HTTP Lab" Add a Result Group "HTTP Lab" Make sure that "Run concurrently" is check marked. Right-click the white area under virtual users and select New Item from the context menu. Change the User Count to 5 Set the Task to the name of new created task. Set the workstation to "Master" 10.Right-click the newly created Test and select Run from the context menu. 11.Examine the newly created test log.
2. In the Events Editor, select OnLoadTestingRequest and click the New button.
251
3. Click the OK button in the New Routine dialog. 4. Add the following code:
[VBScript] Dim SearchValues SearchValues = Array("TestComplete","AQtime","Automated Build Studio") Randomize Sub GeneralEvents_OnLoadTestingRequest(Sender, User, Request) Request.Variables.Item("search") = Escape(SearchValues(Int(3 * Rnd()))) End Sub
[Jscript] var SearchValues = new Array("TestComplete","AQtime","Automated Build Studio"); function GeneralEvents_OnLoadTestingRequest(Sender, User, Request) { Request.Variables.Item("search") = escape(SearchValues[Math.round(3 * Math.random())]) }
5. Right-click on the Test created from the first part of the lab and select Run from the context menu. 6. Examine the Headers for the different user to see the changes in the traffic.
19.11 Summary
In this section, we have learned about HTTP Performance testing and the types of performance testing such as load, stress and scalability. We have learned how to record HTTP traffic and how to modify the traffic before sending request to the web server.
Part
XX
Remote Agent
Remote Agent
253
20
20.1
Remote Agent
Objectives
Remote Agent is a tool that allows for the distribution of HTTP loads tests across a network of computers. In this section you will learn: Installing Remote Agent Running Remote Agent Configuring Remote Agent Using Remote Agent for HTTP Load Testing
20.2
20.3
Console Mode
When running Remote Agent in console mode you'll see this window on your Windows Desktop:
254
To exit Remote Agent from this mode simply activate the window by clicking on it and press Escape.
Service Mode
When Remote Agent is installed in service mode there is no visible UI that will appear. To control the execution of Remote Agent you need to change the settings under Windows Services. In XP, you can view Windows Services Window by running the command "services.msc" from the Run command on the Windows Start menu.
Remote Agent
255
From this window you can right click on TestComplete 6 HTTP Load Testing Remote Agent and change its Startup Type.
20.4
256
tested Web server is installed. There is a proxy server between the Remote Agent computer and the computer where TestComplete executes. If the Remote Agent has direct access to the tested Web site and the TestComplete computer, you may set this option to 0. Default value: 0. proxy host Specifies the proxy server that the Remote Agent uses to connect to the tested Web site and to the computer where TestComplete runs. This can be either the computer name, or IP address. This option is ignored if the use proxy option is set to 0. Specifies the port which the Remote Agent uses to connect to the proxy server specified by proxy host. Default value: 8080. This option is ignored if the use proxy option is set to 0. Specifies the user name under which you want to connect to the proxy server (if it requires user authentication). Specifies the password that confirms the identity of the user under whose name you want to connect to the proxy server (if it requires user authentication).
proxy port
proxy login
proxy password
Note: Do not forget to end the RA process (stop its service) before changing its settings and then restarting RA afterwards.
The XML file appears as follows: <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE Nodes [ <!ENTITY % NameValue "CDATA"> <!ENTITY % PropType "(I|S|D|L|H|B)"> <!ENTITY % VersionValue "CDATA"> <!ELEMENT Prp (#PCDATA)> <!ELEMENT Node (Node|Prp)*> <!ELEMENT Nodes (Node)+> <!ATTLIST Nodes version CDATA "1"> <!ATTLIST Node name CDATA #REQUIRED> <!ATTLIST Prp name CDATA #REQUIRED> <!ATTLIST Prp type CDATA #REQUIRED> <!ATTLIST Prp value CDATA #REQUIRED> ]> <Nodes version="1"> <Node name="root"> <Prp name="proxy host" type="S" value="proxy.domain (undefined)"/>
Copyright 2009 AutomatedQA Corp. - 2.0 Release
Remote Agent
257
<Prp name="description" type="S" value="Workstation's Load Testing service"/> <Prp name="proxy password" type="S" value=""/> <Prp name="use proxy" type="B" value="0"/> <Prp name="proxy port" type="I" value="8080"/> <Prp name="proxy login" type="S" value=""/> <Prp name="ra port" type="I" value="9191"/> </Node> </Nodes>
20.5
Hands on Lab: Working with Remote Agent for HTTP Load Testing
To use Remote Agent you need to setup an HTTP Load Testing project in TestComplete. The Load Testing project has features that allow you to leverage Remote Agent running on multiple machines for testing web applications or services.
258
2. On the Create New Project dialog select HTTP Load Testing and click OK 3. Click the Finish button on the Project Wizard dialog to create your new project Once created the new project will display the following nodes (based on your TestComplete settings your project may vary slightly):
The LoadTesting node contains the items of interest for conducting HTTP Load testing. These nodes
Remote Agent
259
are: Stations - represents the machines that will be conducting the tests. The Master sub-node represents the machine that TestComplete is running on. Tasks - is the HTTP traffic youre interested in testing. Tests - allows you to assign tasks to various stations for test execution.
2. In the Host edit box enter the machine name or IP address. 3. Change the Name edit box to something more meaningful. Note: You'll be able to change all of these settings from the project's Workspace so don't worry if you make a mistake. You can add and remove Stations from your project as necessary from the Project Explorer.
Setting up Tasks
The next step is to create the HTTP traffic you want to load test your server with. The easiest way to produce traffic is using TestCompletes recording facilities.
Copyright 2009 AutomatedQA Corp. - 2.0 Release
260
1. Configure Internet explorer to use TestComplete as a proxy allowing it to monitor and record HTTP traffic. For IE you can do that from the Connections tab of the Internet Options dialog setting the proxy to localhost on port 9999. For Firefox open the Tools | Options dialog and look on the Advanced page, under the Network tab. 2. Click the record button on the TestComplete toolbar and once recording begins click the Record an HTTP Task button (circled in red below):
3. This will bring up the Select Load Testing dialog where you can decide to record a new HTTP traffic or append it to an existing task. 4. Once you click OK you can begin recording HTTP traffic by simply using your browser. TestComplete will record the HTTP traffic and add it to the task you specified.
At this point, you're ready to leverage Remote Agent and execute your tests harnessing the power of your networked machines to HTTP Load Test your web applications.
Remote Agent
261
20.6
Summary
Remote Agent is a tool that allows for the distribution of HTTP loads tests across a network of computers. With Remote Agent installed a single TestComplete user can quickly and easily harness the power of a network to provide real world load testing of HTTP based web applications. In addition, Remote Agent has a small footprint and separate install allowing it to be easily deployed for rapid HTTP load testing.
Part
XXI
Distributed Testing
Distributed Testing
263
21
21.1
Distributed Testing
Objectives
This section explains how tests are run on several computers at the same time. In this section you'll learn: What is a Distributed Test. What are the parts of a Distribute Test. How to setup a Distributed Test. How to use SyncPoints. How to use Network Suite Variables.
21.2
Network Suites
Distributed Testing is the ability of TestComplete to control test cases running on several computers at the same time. In addition to running the tests, the computers involved can communicate with each other using TestComplete. In order to perform a distributed test, all projects involved must contain the Network Suite project item. In addition, all the computers involved must have the same version of TestComplete/ TestExecute on them (including the minor version number). Most of the setup of a distributed test, takes place in the master project. The minimum you need to run a distributed test is a master project with at least one host machine and at least one task for that host machine to run. The root level of Distributed Testing is the Network Suite:
The workspace editor for NetworkSuite consists of three parts: 1. Properties - This is where you can setup a shared path for all the computers to use in testing. TestComplete uses this path to create a network shared folder during the run of the network suite.
264
2. Variables - Using these variables, the computers involved in the test can pass data to each other. This data can only be of types; string, integer, double or Boolean.
3. Run State - This displays the state of each computer during the test run.
Distributed Testing
265
21.3
Hosts
Hosts are the secondary computers involved in the test. Hosts need to have either TestComplete or TestExecute on them and can be addressed by either name or IP address. The base path is where the computer will start looking for the project to run the test (not required).
Since firewall and other network communication issues can happen, it is recommend that you verify the existence of the host. Right-click the workspace to get the context menu and click Verify.
266
21.4
Jobs/Tasks
Jobs and Tasks are where tests to be run are controlled. A Job consists of one or more host computers tasks. Each job is run to completion before the next job is run. Under each Job are the Tasks (tests) to be run on the host computer. Each host computer can only be used once in a job for an active task.
Tasks have the following properties: 1. Active - Whether or not the test is run. 2. Name - Name of the task. 3. Path - Path to the TestComplete project that holds the test to be run (relative to the host computer). 4. Copy the remote log - Controls if the master computer gets a copy of the log file from the host computer.
5. Action after run - Determines the action to take after the test completes on the host computer.
Distributed Testing
267
6. Tag - A value sent to the host computer at the start of the test. 7. Test - The test to be run. If left blank it will be the project/project suite from the path property. 8. Use previous instance - Controls what to do if TestComplete/TestExecute is already running on the host computer.
21.5
SynchPoints
SynchPoints delay execution of the test until all computers with that synch point name reach the synchronization point. When all the computers with a named SynchPoint hit that Synchronize Point, they will continue on with their test. An example of an effective use for SynchPoints: you want to avoid where two or more users try to edit the same record at the same time and post the data.
268
21.6
Setup
Simple Distributed Test
1. Create a master project with a NetworkSuite Project Item. 2. Create a hosted (slave) project with a NetworkSuite Project Item.
3. Add notepad to the TestedApps project Item of the hosted project. 4. Modify the File Path property of the TestedApp to "" (blank) 5. Create (or record) a script method to type something into notepad.
[VBScript] Sub Test1 Dim p1 Dim w1 TestedApps.notepad.Run Set p1 = Sys.Process("notepad") Set w1 = p1.Window("Notepad", "*").Window("Edit") w1.HScroll.Pos = 0 w1.VScroll.Pos = 0 Call w1.Click(135, 29) Set w1 = p1.Window("Notepad", "*") Call w1.Window("Edit").Keys("TestComplete Training - Distributed Testing") w1.Close p1.Window("#32770", "Notepad").Window("Button", "&No").ClickButton End Sub
Distributed Testing
269
[JScript] function Test1() { var p1 var w1 TestedApps.notepad.Run(); p1 = Sys.Process("notepad"); w1 = p1.Window("Notepad", "*").Window("Edit"); w1.HScroll.Pos = 0; w1.VScroll.Pos = 0; w1.Click(135, 29); w1 = p1.Window("Notepad", "*"); w1.Window("Edit").Keys("TestComplete Training - Distributed Testing"); w1.Close(); p1.Window("#32770", "Notepad").Window("Button", "&No").ClickButton(); }
6. Save the project. 7. Select the NetworkSuite Project Item in the Master Project and enter the path to the project suite in the Shared Path.
8. Expand the Hosts Project Item and select Host1 9. Enter the name (or IP address) of the hosting (slave) computer. 10.In the Base path property enter "\\<Master Computer Name>\<Name of Project Suite directory>"
11.Right-click on Host1 and select Verify from the context menu. 12.Expand the Jobs Project Item. 13.Expand the Job1 Project Item. 14.Select the Task1 Project Item. 15.In the Path property enter "\<Name of Hosted Project>\<Name of Hosted Project>.mds".
Copyright 2009 AutomatedQA Corp. - 2.0 Release
270
16.In the Copy remote log property select "[Always]". 17.In the Use previous instance property select "[Use]". 18.In the Test property enter "<Name of Hosted Project>\Script\Unit1\Test1".
19.Right-click Task1 and select Verify from the context menu. 20.With verification, the NetworkSuite is ready to run. Right-click the NetworkSuite project item and select Run from the context menu.
[VBScript] Sub Test1 Dim p1 Dim w1 TestedApps.notepad.Run Set p1 = Sys.Process("notepad") Set w1 = p1.Window("Notepad", "*").Window("Edit") w1.HScroll.Pos = 0 w1.VScroll.Pos = 0 Call w1.Click(135, 29) Set w1 = p1.Window("Notepad", "*") Call w1.Window("Edit").Keys(NetworkSuite.Variables.Var1) w1.Close p1.Window("#32770", "Notepad").Window("Button", "&No").ClickButton End Sub
Distributed Testing
271
w1 = p1.Window("Notepad", "*").Window("Edit"); w1.HScroll.Pos = 0; w1.VScroll.Pos = 0; w1.Click(135, 29); w1 = p1.Window("Notepad", "*"); w1.Window("Edit").Keys(NetworkSuite.Variables.Var1); w1.Close(); p1.Window("#32770", "Notepad").Window("Button", "&No").ClickButton(); }
2. Add the variable "Var1" to the master project. 3. Change the Local Value property to "TestComplete Rocks" 4. Right-click the NetworkSuite project item and select Run from the context menu. On the host (slave) computer, you will see "TestComplete Rocks" typed into notepad.
Synchronizing Computers
There are times when you want to have one computer wait for another computer to complete at least part of its task before finishing the first computer's task. For example, you want the consumer's computer to wait until the bank's computer has processed a debit before the consumer's computer checks its balance. We will show a couple of ways to synchronize. Using SyncPoints 1. Modify the test in hosted (slave) project.
[VBScript] Sub Test1 Dim p1 Dim w1 TestedApps.notepad.Run Set p1 = Sys.Process("notepad") Set w1 = p1.Window("Notepad", "*").Window("Edit") w1.HScroll.Pos = 0 w1.VScroll.Pos = 0 Call w1.Click(135, 29) Set w1 = p1.Window("Notepad", "*") Call w1.Window("Edit").Keys(NetworkSuite.Variables.Var1) Call w1.Window("Edit").Keys("[Enter]") NetworkSuite.Synchronize("SynchPoint1") Call w1.Window("Edit").Keys(NetworkSuite.Variables.Var1) w1.Close p1.Window("#32770", "Notepad").Window("Button", "&No").ClickButton End Sub
272
[JScript] function Test1() { var p1 var w1 TestedApps.notepad.Run(); p1 = Sys.Process("notepad"); w1 = p1.Window("Notepad", "*").Window("Edit"); w1.HScroll.Pos = 0; w1.VScroll.Pos = 0; w1.Click(135, 29); w1 = p1.Window("Notepad", "*"); w1.Window("Edit").Keys(NetworkSuite.Variables.Var1); w1.Window("Edit").Keys("[Enter]"); NetworkSuite.Synchronize("SynchPoint1"); w1.Close(); p1.Window("#32770", "Notepad").Window("Button", "&No").ClickButton(); }
2. Right-click the SyncPoints Project Item, select Add | New Item... from the context menu. 3. Hit Enter on the Create Project Item dialog. 4. Create a script in the master project.
[VBScript] Sub Test1 NetworkSuite.Run(false) NetworkSuite.WaitForState(ns_Running) Delay(30000) NetworkSuite.Variables.Var1 = "Rocks" NetworkSuite.Synchronize("SynchPoint1") NetworkSuite.WaitForState(ns_Idle) End Sub
[JScript] function Test1() { NetworkSuite.Variables.Var1 = "TestComplete"; NetworkSuite.Run(false); NetworkSuite.WaitForState(ns_Running); Delay(30000); NetworkSuite.Variables.Var1 = "Rocks"; NetworkSuite.Synchronize("SynchPoint1"); NetworkSuite.WaitForState(ns_Idle); }
5. Right-click the SyncPoints Project Item, select Add | New Item... from the context menu. 6. Hit Enter on the Create Project Item dialog. 7. Right-Click in the newly created script and select Run Current Routine from the context menu.
Distributed Testing
273
On the hosted computer, "TestComplete" will be typed, followed by a delay and then on a new line "Rocks" will be typed. Using NetworkSuite Variables 1. Modify the test in hosted (slave) project.
[VBScript] Sub Test1 Dim p1 Dim w1 TestedApps.notepad.Run Set p1 = Sys.Process("notepad") Set w1 = p1.Window("Notepad", "*").Window("Edit") w1.HScroll.Pos = 0 w1.VScroll.Pos = 0 Call w1.Click(135, 29) Set w1 = p1.Window("Notepad", "*") Call w1.Window("Edit").Keys(NetworkSuite.Variables.Var1) Call w1.Window("Edit").Keys("[Enter]") NetworkSuite.Variables.Var2 = True Call NetworkSuite.WaitForNetVarChange("Var2",false) Call w1.Window("Edit").Keys(NetworkSuite.Variables.Var1) w1.Close p1.Window("#32770", "Notepad").Window("Button", "&No").ClickButton End Sub
[JScript] function Test1() { var p1 var w1 TestedApps.notepad.Run(); p1 = Sys.Process("notepad"); w1 = p1.Window("Notepad", "*").Window("Edit"); w1.HScroll.Pos = 0; w1.VScroll.Pos = 0; w1.Click(135, 29); w1 = p1.Window("Notepad", "*"); w1.Window("Edit").Keys(NetworkSuite.Variables.Var1); w1.Window("Edit").Keys("[Enter]"); NetworkSuite.Variables.Var2 = true; NetworkSuite.WaitForNetVarChange("Var2",false); w1.Window("Edit").Keys(NetworkSuite.Variables.Var1); w1.Close(); p1.Window("#32770", "Notepad").Window("Button", "&No").ClickButton(); }
274
[JScript] function Test2() { NetworkSuite.Variables.Var1 = "TestComplete"; NetworkSuite.Run(false); NetworkSuite.WaitForNetVarChange("Var2",true); NetworkSuite.Variables.Var1 = "Rocks"; NetworkSuite.Variables.Var2 = false; NetworkSuite.WaitForState(ns_Idle); }
3. Add the variable "Var2" to the master project in the NetworkSuite project item. 4. Right-click in the newly created script and select Run Current Routine from the context menu. The hosted computer will do the same things as the SyncPoint demo, but with less delay in the project. Notice that the hosted computer can pass data back to the master computer.
21.7
Summary
In this section we learned how tests are run on several computers at the same time. We also learned how to script Distributed Tests using Synchronize Points and Network Suite Variables.
Part
XXII
User Forms
276
22
22.1
User Forms
Objectives
This section demonstrates how to create user forms and manipulate them using script: In this section you'll learn: What is a user form. Learn how to create an user form. How to access user forms in script.
22.2
Creating
Creating a user form in TestComplete is very similar to creating a form in most development IDEs (Visual Studio, Eclipse, Rad Studio). First add the UserForms project Item to the project. The UserForms project item is a holder (folder) for all the user forms created in the project. The next step is to add an user form to the project (right-click of the UserForms project item and Add | New Items...). In our example, we will create a simple user name and password dialog.
The left side of the editor contains the components that can be added to the user form. The middle is the actual user form. And the right side is where the properties and events are setup. Components are added by dragging with the mouse and dropping on the form. The components that we use are TcxTextEdit (from the Editors Category), TcxButton (Buttons Category) and TcxLabel (Helpers Category). We will use two of each.
User Forms
277
We will also need to set the properties for all of the components (only changed properties shown): Property User Form Caption Height Width cxButton1 Caption Default ModalResult cxButton2 Cancel Caption ModelResult cxLabel1 Caption cxLabel2 Caption edtUser (Renamed from cxTextEdit1) Password: User Name: True Cancel mrCancel OK True mrOK Enter Login Information: 130 450 Value
278
edtUser
edtPassword eemPassword
22.3
Scripting
Now that we have created a user form, we need to learn how to use the form in a script. There are two method used to display an user form - Show() and ShowModal(). In our example we will use ShowModal (), which displays the user form and stops the script from playing until the user answers the dialog. Note: Show() will continue with the next line in the script code.
[VBScript] Sub Main 'Fill in the current user name UserForms.UserNameAndPassword.edtUser.Text = Sys.UserName if UserForms.UserNameAndPassword.ShowModal = mrCancel Then Runner.Halt("User Cancelled Test") end If Log.Message("User: " & UserForms.UserNameAndPassword.edtUser.Text &_ " Logged in with Password: " &_ UserForms.UserNameAndPassword.edtPassword.Text) End Sub
[JScript]
function Main() { //Fill in the current user name UserForms.UserNameAndPassword.edtUser.Text = Sys.UserName; if (UserForms.UserNameAndPassword.ShowModal() == mrCancel) Runner.Halt("User Cancelled Test"); Log.Message("User: " + UserForms.UserNameAndPassword.edtUser.Text + " Logged in with Password: " + UserForms.UserNameAndPassword.edtPassword.Text); }
22.4
Summary
In this chapter, we learned the basics of creating a user form. Then we learned how to display the form to the user and get information from the form.
Part
XXIII
Best Practices
280
23
23.1
Best Practices
General
The following are general tips and best practices to help you get the most out of TestComplete: Record/Playback is a quick and easy way to get automated tests up and running but tend to be brittle leading to problems when the application changes, etc. Use the TestItems of the project as a framework for Test Cases.
Separate Data from the Test Framework (see Data-Driven Testing). Use the code metrics of the Code Explorer to improve the quality of the script code.
Best Practices
281
Use reusable routines whenever possible. Keep routines short (less than a page of code). Use meaningful variable names (The default variable names of a recording are not very good variable names).
282
23.2
Web Page
The following are tips for making effective use of TestComplete when testing web pages: Make the Page object a child of the browser process.
Part
XXIV
Cheat Sheet
284
24
24.1
Cheat Sheet
Keyboard Shortcuts
Global Shortcuts (keys that work when TestComplete is running even if TestComplete does not have focus) Command Pause script execution Fix Information Record Stop Run Pause recording Load Testing Record Low Level Record Default Key SHIFT-10 SHIFT-CTRL-A SHIFT-F1 SHIFT-F2 SHIFT-F3 SHIFT-F11 SHIFT-F6 SHIFT-F4
Key Mapping (keys that work when TestComplete has focus, generally in the editors) Command/Section Debugging Run Reset Step Over Trace Into Run to Cursor Switch Breakpoint View Evaluate View Call Stack View Watches View Break Points Project/Units Close Page CTRL-F4 CTRL-F4 ALT-F3 F9 CTRL-F2 F8 F7 F4 F5 CTRL-F7 CTRL-ALT-S CTRL-ALT-W CTRL-ALT-B F5 SHIFT-F5 F10 F11 F4 F9 CTRL-F2 ALT-7 ALT-3 CTRL-B F9 CTRL-F2 F8 F7 F4 CTRL-F8 CTRL-F4 CTRL-ALT-S CTRL-ALT-W CTRL-ALT-B Default Visual Studio Borland Classic
Cheat Sheet
285
Save Unit Open Project New Project Save All Display previous page Display next page Cursor movement Cursor Left Cursor Right Beginning of Line End of Line Up one line Down one line Up one page Down one page Beginning of Document End of Document Move to word before Move to word after Delete operations
CTRL-S CTRL-F11
CTRL-S CTRL-F11
CTRL-SHIFT-TAB CTRL-TAB
CTRL-SHIFT-TAB CTRL-TAB
LEFT RIGHT HOME END UP DOWN PGUP PGDN CTRL-HOME CTRL-END CTRL-LEFT CTRL-RIGHT
LEFT RIGHT HOME END UP DOWN PGUP PGDN CTRL-HOME CTRL-END CTRL-LEFT CTRL-RIGHT
LEFT RIGHT HOME END UP DOWN PGUP PGDN CTRL-PGUP CTRL-PGDN CTRL-LEFT CTRL-RIGHT
Delete character at cursor DEL Delete character before cursor Delete current line Delete previous word Delete next word Miscellaneous Indent selected block Unindent selected block CTRL-SHIFT-I or TAB BACKSPACE CTRL-Y CTRL-BACKSPACE CTRL-T
CTRL-SHIFT-I
CTRL-SHIFT-I CTRL-SHIFT-U
286
ALT-SHIFT-BACKSPACE ALT-SHIFT-BACKSPACE Print CTRL-P CTRL-P CTRL-UP CTRL-DOWN ALT-F10 (Code Editor only) CTRL-F CTRL-H F3 CTRL-A CTRL-SPACE CTRL-J CTRL-SPACE CTRL-J CTRL-P CTRL-W CTRL-Z ALT-F10 (Code Editor only) CTRL-F CTRL-R CTRL-L
Scroll display up one line CTRL-UP Scroll display down one line Display context menu Find Replace Search Again Select All Invoke Code Completion Code Templates Bookmarks Set Numbered Bookmark CTRL-SHIFT-# Goto Numbered Bookmark Set Unnumbered Bookmark Goto Unnumbered Bookmark Clipboard Cut to Clipboard Copy to Clipboard Paste from Clipboard CTRL-X or SHIFT-DEL CTRL-C or CTRL-INS CTRL-V or SHIFT-INS CTRL-# CTRL-SHIFT-' CTRL-' CTRL-DOWN ALT-F10 (Code Editor only) CTRL-F CTRL-R F3 CTRL-A CTRL-SPACE CTRL-J
24.2
Code Completion
TestComplete will automatically display the code completion dialog by default. If you accidentally close
Cheat Sheet
287
this dialog (or you have turned Autocompletion off), the code completion dialog can be invoked by press "CTRL-SPACE"
For method known by TestComplete, you can find out what parameters are needed by the method by pressing "CTRL-SHIFT-SPACE" inside the parentheses.
24.3
288
Command Pause script execution Fix Information Record Stop Run Pause recording Load Testing Record Low Level Record
Default Key SHIFT-10 SHIFT-CTRL-A SHIFT-F1 SHIFT-F2 SHIFT-F3 SHIFT-F11 SHIFT-F6 SHIFT-F4
24.4
Cheat Sheet
289
Select the Action Type in the new keyboard shortcut (note: if it is already in use, you will need to clear the one using it first). To access and change the keyboard emulation: Select "Tools | Customize Keyboard..." from the main menu. Choose the keyboard emulation that you want. (You can also set keyboard shortcuts for any command in this dialog).
290
Part
XXV
AutomatedQA
292
25
25.1
AutomatedQA
History
AutomatedQA offers software products and services for development and quality assurance projects worldwide. They create innovative, award-winning and affordable products for the entire software development lifecycle including TestComplete for test automation and AQtime, a sophisticated performance and memory profiler. AutomatedQA has an impressive list of customers ranging from huge teams in the world's largest organizations to progressive one-developer shops. AutomatedQA was founded in 1999 with headquarters in Las Vegas, Nevada, United States. AutomatedQAs guiding principle is to be wholly focused on providing affordable and feature-rich developer tools and quality assurance technologies, and on providing users with fast and accurate product support each and every day. What does affordable and feature-rich mean? It means bang for the buck. It means that their solutions tend to cost a fraction of their competitor's prices and offer more features. A good example is their automated testing tool, TestComplete. Some of their competitors charge separately for different test types like GUI testing, unit testing and load testing. TestComplete includes all supported testing types in one product with more features, for considerably less. Its this combination of affordability and features that led Joel Spolsky, of joelonsoftware.com to write, AutomatedQA's TestComplete is a great product and just as capable as the market leader at less than one-tenth the price. Why would anybody pay $6000 per seat for test automation?. -- Joel Spolsky
25.2
Product Offerings
AutomatedQA offers several products in the Software Application LifeCycle Management sector. This include TestComplete, AQtime, Automated Build Studio, AQdevTeam and other derivatives of the main products like TestExecute and TestRecorder.
AQtime
Debug, Optimize, and Deliver Rock Solid Applications AQtime is AutomatedQA's award-winning performance profiling and memory and resource debugging toolset for Microsoft, Borland, Intel, Compaq and GNU compilers. The latest version of AQtime, AQtime 6, includes dozens of productivity tools that help you easily isolate and eliminate all performance issues and memory/resource leaks within your code by generating comprehensive and detailed reports for your .NET and Windows applications. AQtime supports .NET 1.0, 1.1, 2.0, 3.0 and 3.5 applications and Windows 32- and 64-bit applications. AQtime is built with one key objective - to help you completely understand how your programs perform during execution. Using its integrated set of performance and debugging profilers, AQtime collects crucial performance and memory/resource allocation information at runtime and delivers it to you both in summarized and detailed forms, with all of the tools you need to begin the optimization process. This is all done without modifying the application's source code! With AQtime's intuitive and user-friendly interface and instrumentation in hand, you will quickly know the exact speed, memory usage, and application usability issues in your programs. As you optimize and improve your code, AQtime provides all the tools to compare and merge results so that over time, an exact
AutomatedQA
293
and accurate "picture" of your application's state takes shape: Monitor and report on all areas that could degrade your projects performance and quality. Assess the thoroughness of your tests by using Coverage Profiling. Ensure that you make the right code improvements from day one. Helps drill down to the exact line of source code that is responsible for performance or memory allocation inefficiencies.
294
automate repetitive or day-to-day tasks with the single click of a button. Even though the product name includes the word build, you can use Automated Build Studio to automate any common or everyday tasks in your organization. Automated Build Studio contains over 540 built-in operations that will help you: Compile applications Create installation packages Perform automated builds as scheduled tasks Get and put files from/into version control systems Label sources in version control systems Compile help files Create, modify and delete registry keys and INI file settings Copy and move files to a location (network drive, Web site, FTP server, etc.) Extract and pack files from/to ZIP and RAR archives Run automated test scripts and profilers Post bug reports to issue-tracking systems Send and receive e-mail, ICQ and newsgroup notifications Burn CDs and DVDs Register COM and .NET components Perform scripting operations in any of 3 scripting languages (VBScript, Jscript or DelphiScript) or many other operations...
AutomatedQA
295
TestExecute
TestExecute allows you to execute scripts written with TestComplete and log test results on machines that do not have TestComplete installed - using a simple, resource friendly command-line utility. TestExecute gives QA departments the ability to test applications in real life user environments - such as at customer sites - without the need to install TestComplete on the target machine.
296
TestRecorder
TestRecorder is a set of runtime libraries to be distributed with your 32-bit and 64-bit applications. Once incorporated into your app, TestRecorder fully records end-user actions in the binary format. Later, the recorded data can be converted with TestComplete to an easily readable script code in VBScript, Jscript, DelphiScript, C++Script or C#Script. These scripts tell you exactly what a user was doing during application execution - allowing you to accurately repeat the sequence of user actions via TestComplete or TestExecute.
Part
XXVI
Professional Offering
298
26
Professional Offering
Services
AutomatedQAs worldwide network of partners can provide your organization with training and services to help you ramp up more quickly or help with your existing automated testing projects. Go to www.automatedqa.com/partners to find a partner that fits your needs.
Professional Offering
299
TestComplete Consultant working with you live over the phone and via GotoMeeting so you can virtually work shoulder to shoulder to get you going quickly. http://store.falafel.com/p-70-testcomplete-consulting-express.aspx Video Training Online from Falafel Software Falafel Software provides an abundance of training videos allowing you to learn at your own pace in an innovative environment simply browse to http://tv.falafel.com/ for more information. For more info on Falafel Software, go to www.falafel.com or call 1-888-GOT-FALAFEL (1-888-4683252).
300
Index
-..NET 12, 57
-332 bit 12
Code Options 61 Code Templates 61 Complex types 219 Condition 63 Connections 241 Consulting 298 Continuous Integration 37, 39 Cookie Handling 239 Copy Script to Editor 48 CPU 47 CSVDriver 165 Customize 42
-664 bit 12
-DDDT 165 Debugging 63, 64, 65, 66 Delay 136 DHTML 205 Distributed Testing 36, 268 DOM 196 DUnit 104
-AActivate 136 ActiveFocus 142 Add Text To Script 128 ADO 183 ADODriver 165 AJAX 205 Aliases 102 Analysis 244 AppendFolder 89 Application 36 AQDevTeam 292 AQTime 292 Automated Build Studio 292 AutomatedQA 12, 292
-EEditor 59, 60 Email 90 Eric Holton 292 Evaluate 66 ExcelDriver 165 Extended Information
89
-FFile Comparison 150 Files 150 Find 203 Finder tool 50 Firewall Settings 237 Functional Testing 36
-CCall Stack 64 Checkpoint 142, 150, 154 Code Completion 59, 286 Code Explorer 44, 280
Index
301
-HHighlight Object 99 Highlight on Screen 50 Hosts 265 HTTP Load Test 268 HTTP Load Testing 237, 239, 242, 253 HTTP Performance Testing 36 HTTP Traffic 246 Hybrid 196
-NNamed Mappings 94, 99, 101, 102 Naming convention 197 NativeWebObject 203 Network Suites 263 Notepad 50 NUnit 104, 105
-OObject Browser 47 Object Comparison 154 Object Name Mapping 101 Object Properties 48 Objects 154 OnBeforeStep 120 OnLogError 175 OS 47
-PParameter Completion 59, 286 Pass Count 63 Pausing 130 Playback 126 Plug-ins 84 PopLogFolder 89 Process Filter 48 Professional Offering 298 Profile 85 Project Anatomy 75 Project Explorer 44 Project Item 44, 75 Project Items 84 Project Structure 75 Project Suite 44 Project Template 79 Project Wizard 75 Project Worksapce 44 Proxy Settings 237
-LLoad Testing 36, 237 Local Variables 65 Locals 65 LockEvents 91 Log Tree 89 Low Level Procedure 133 Low Level Procedure Collection
133
-MManual Steps 113 Manual Test 120 Map to Object 94 Mapping Dialog 101 Maunal Test 112, 113 Maunal Test Events 120 Maunal Testing 36 Menus 42 Mouse events 136 MSTest 104
-QQA 36
302
-RR&D 36 RAM 47 Recording 126, 129, 239 Recording Toolbar 127 Reflection 57 Region Comparison 142 Regions 142 Regression Testing 36 Remote Agent 253, 255 Remote Agent Port 255 Remote Agent Proxy 255 Requests 241, 246 Responses 241, 246 Result Logs 44, 244 Run As 85 Run Mode 85
TestComplete 12, 292 TestedApps 85 TestExecute 292 TestRecorder 292 Tests 239 Toolbar 42 Training 298 Tree 196
-UUnexpected Windows 176 Unit Testing 36, 104, 108 User Forms 276, 278
-SScalability Testing 237 Screen Coordinates 133 script Log 89 Service mode 253 SetFocus 136 Shortcuts 284, 287, 288 ShowModal 278 Smoke Test 39 Sort 48 Source Code Control 37 SQL Server 183 SQL Server 2005 183 Stations 239, 257 Stopping 130 Stress Testing 237 SynchPoints 267
-WWatch List 66 Web Accessibility Checkpoint 200 Web Comparison Checkpoint 197 Web Page 282 Web Page Model 196 Web Services Options 224 Web Services Testing 214, 219, 226 Web Services Testing Dialogs 224 Web Testing 205 WebServices Checkpoint 219 White Box 56 White Box Application 57 Window Coordinates 133 Windows 12 WinformsObject 57 WndCaption 50 Workspace 44 WSDL 214
-TTag 196 Tasks 239, 257, 266 TCUnitTest 104 Test Items 280 Test Log 244 Test Logs 90