Why VBScript in QTP Still Comes Up in Interviews
QTP, which HP later rebranded to UFT, is legacy software at this point. But interviewers still pull it because a lot of older automation frameworks haven't been migrated out. If you're preparing for a role that touches maintenance work on an existing HP portfolio, you need to know VBScript well enough to not look lost when they ask. I spent years working on legacy UFT suites where the entire object repository and recovery scenarios were built on VBScript. Here's what actually gets asked and what people tend to get wrong. This is the section where people usually want to look smart by reciting definitions. Don't bother. The real questions test whether you've actually written code inside a QTP action and debugged it when something broke at 11 PM before a release. What is the difference between a Function and a Sub in VBScript?
A Function returns a value. A Sub doesn't. That's the textbook answer. The practical answer is that in QTP, you use Subs for actions that perform operations like clicking buttons or entering data, and Functions when you need to pass a result back to the calling action. I remember one case where I wrote a Function that returned a boolean indicating whether a dialog had appeared within a timeout window. The tester before me had used a Sub for that same task and was checking a global variable to see if the dialog showed up, which made the code fragile and nearly impossible to debug across multiple runs. How do you handle dynamic object identification in QTP? QTP relies on the Descriptive Programming model when objects can't be found in the Object Repository. You create descriptions programmatically using the Description object. For example, if a button's index changes every time the application restarts, you don't redefine the object in the repository. You write a Description object that captures properties like the "html id" or "accessible name" that actually stay stable across sessions.
Here's a concrete example from my experience. I was working on a web application where the login button had a dynamic class name generated by the server at runtime. The only consistent property was the "innertext" set to "Sign In" and the "tag" set to "INPUT". I built a descriptive programming call using those two properties and wrapped it in a reusable function. That saved me from updating the repository every single build. Explain the different types of Object Repositories in QTP. There are two main approaches: per-action repositories and shared repositories. A per-action repository creates a separate .tsr file for each action. A shared repository is one central .tsr file that multiple actions reference. Shared repositories make collaboration easier but create version control headaches. If two people edit the same shared repository at the same time, you get merge conflicts that QTP doesn't handle gracefully. I used to lock the shared repository with a flag file on the network drive as a workaround. Someone always forgets to unlock it, but it's better than corrupting the object repository mid-sprint.
Get the Full Details

What is the purpose of the Recovery Scenario Manager? Recovery Scenarios let you define what happens when a test hits an unexpected situation like a pop-up dialog or an application crash. You configure trigger conditions, recovery operations, and post-recovery actions. Without recovery scenarios, a single unexpected browser dialog can crash your entire test run and force a manual rerun. I once dealt with a scenario where a flash-based ads overlay appeared randomly on a critical e-commerce checkout flow. The test kept failing because the overlay wasn't in the Object Repository and QTP couldn't find the Continue button. I set up a recovery scenario that triggered on the presence of a window with the title "Advertisement" and added a recovery operation to close that window, then resumed the test. It cut our false failure rate from about 40% down to under 5%. The ads weren't deterministic, so no amount of object identification could handle that consistently.
How do you read and write to external files like Excel or CSV from VBScript in QTP? QTP has built-in support for the QuickTest Professional.DataTable object, which acts as an in-memory spreadsheet. You can parameterize tests using the Action Local Data Table or the Global Data Table. For reading external Excel files, you typically use the Excel.Application COM object. For CSV files, you use FileSystemObject with TextStream. One detail people miss is that the Excel COM object keeps running in the background if you don't explicitly quit it. I had a test suite that would create dozens of zombie Excel processes over a long regression run. The fix was simple: add a Finally block that calls .Quit and sets the object to Nothing after every file operation. That cleaned up the processes reliably.
What is the difference between Expected Output and Checkpoints? Expected output is the result you anticipate from an operation, like a page title or a text string. Checkpoints verify that result against what QTP records. There are several checkpoint types: standard text checkpoint, image checkpoint, accessibility checkpoint, XML checkpoint, database checkpoint, and page statistics checkpoint. The most commonly used ones in day-to-day work are text and image checkpoints. Image checkpoints are tricky because pixel-level matching fails when the application runs on a monitor with a different DPI setting. I learned this the hard way when a test passed on my machine at 100% scaling but failed on a CI server running at 125% scaling. The workaround was to switch to bounding box matching or to use a text-based checkpoint instead whenever possible.

How do you handle errors in VBScript used inside QTP? VBScript uses On Error Resume Next to suppress errors and let execution continue. You then check the Err object's Number property to see if an error occurred. In QTP specifically, errors during test execution can either be caught by recovery scenarios or cause the action to stop depending on how you've configured the run settings. For robust scripts, I use On Error Resume Next combined with explicit Err.Clear calls after each operation I expect might fail. One edge case that tripped me up for a while: when using On Error Resume Next, if a subsequent line also triggers an error, the Err.Number from the first error can linger and mask the second one. The fix is to always call Err.Clear immediately after handling the error or checking the condition. I now treat Err.Clear as a mandatory step rather than something optional.
Explain Regular Expressions in QTP Object Identification. You can enable regular expression matching on any string property in the Object Repository or in descriptive programming. When enabled, QTP treats the property value as a regex pattern instead of a literal string. This is useful for objects whose values change in a predictable pattern, like sequence numbers or timestamps embedded in element IDs. The property is "regarx" and it's set to True on the Description object. A common pitfall is forgetting that regular expressions in VBScript don't support possessive quantifiers or lookaheads in the same way JavaScript does. The regex engine used here is older and more limited, so keep your patterns simple. I once wrote a complex regex with alternation that looked correct on paper but failed because of a character class limitation in VBScript's regex engine. Simplifying it to a straightforward pattern with a wildcard resolved the issue.
What is Smart Identification in QTP? Smart Identification is a fallback mechanism that kicks in when QTP can't find an object using its recorded properties. It uses mandatory properties (which must match), auxiliary properties (which help narrow results), and optional filter properties. QTP builds a filter expression from these and searches for a matching object. If Smart Identification finds a unique match, the test continues. If it finds multiple matches or no match, the test fails. The problem with Smart Identification is that it slows down test execution significantly because it has to rebuild the object description and search through the application multiple times. In one project, enabling Smart Identification on a high-traffic test suite added roughly 30% to the total runtime. I recommend disabling it where possible and relying on proper descriptive programming instead. Use it only for objects that genuinely change their properties unpredictably.
How do you call one QTP action from another action? You can call an action from another action using the ExecuteAction method or by inserting a Call to Existing Action step. When you call an action, you can pass parameters to it and receive return values if the called action is configured to return them. Parameter passing uses the Dictionary object or named arguments depending on how the action is set up. One thing that causes confusion is the distinction between importing an action and calling it. Importing copies the action into your test, while calling references the original action. If you import and modify the imported copy, changes to the original action won't propagate. I always use Call to Existing Action unless there's a specific reason to create a local copy.
What are the limitations of VBScript in QTP that you should know? VBScript doesn't support classes, namespaces, or multiple inheritance. You can simulate classes using the Class statement in VBScript 5.6 and later, but it's limited. It doesn't have try-catch blocks, so error handling is awkward. It doesn't support lambda expressions or closures. It's case-insensitive by default, which leads to bugs when you mix casing inconsistently and then try to debug at midnight. The biggest practical limitation is that VBScript doesn't integrate well with modern web technologies. jQuery, Angular, React, and similar frameworks produce dynamic DOM structures that the traditional QTP object hierarchy struggles to map. When I've worked on applications built with these frameworks, the standard QTP approach breaks down quickly. The alternative in those cases is to use JavaScript injection through the Browser object's ExecuteScript method, or to migrate the automation framework entirely to something like Selenium with a more capable language.
How do you debug a failing QTP test? The first step is always checking the Results window to see the exact step and error message. QTP provides a Step-by-Step view and a Breakpoint feature. You can set breakpoints on any line and step through the script. The Locals window shows variable values at runtime. For object identification failures, the Object Spy tool is essential for inspecting the actual properties of the UI element at runtime. A tip that isn't commonly mentioned: the Event Log in the Results view often contains warnings that don't appear in the error message but explain why an operation failed. I once spent two hours debugging a button click failure only to find in the Event Log that the browser window had focus on a different tab. The click went to the wrong frame. Checking the Event Log would have saved me an hour and a half.
