Continued from previous article – Designing Hybrid Framework in QTP (Part 1). In this article, we will start looking at the process of creating a hybrid framework from scratch. This article would concentrate more on the coding aspects of the hybrid framework. We will start with a basic test script and then would build upon it by incorporating more features to it.
Topics that will be covered in this article
In this article, we will cover the following aspects of the hybrid framework –
a) Identifying the test cases that will be automated as part of this framework
b) The plan or approach as to how the framework will be created
c) Folder structure and writing the first test case
d) Applying the modular framework features in this hybrid framework
Test Cases that will be automated
As a part of this hybrid automation framework, we will automate the following test cases. The application that we will use would be mercury flight reservation system (windows version) and the version of QTP would be QTP 10. Even though we are using QTP 10, you would be able to execute the same test cases in the later versions without any issues.
1) TC01_CreateOrder: The flow of this test case would be to login to the application, create an order and then logout
2) TC02_CreateAndUpdateOrder: For this test case, the flow would be: login >> create order >> search order >> logout
3) TC03_CreateAndDeleteOrder: Here, the flow of the test case would be like this: login >> create order >> search order >> delete order >> logout
Basic approach to create the hybrid framework
As mentioned earlier, the hybrid framework that you will create here will consist of a lot of components and features that will be interlinked with each other. So, in order to create the framework from scratch, you will need to have a plan or an approach. You simply can’t go on doing random stuff and assume that the components and features would somehow get linked together at the end.
The most basic approach (and also the safest one) is to start with a small and easy chunk. This small chunk should be something that can be executed, for example a test case. You should then execute this test case and make sure that it works fine. After this is done, you should then start adding other components and features around it. After the addition of each component, you should execute your code to make sure that things work fine.
By following this approach you would be able to add all the components together to come up with your hybrid framework. And since you added all these components over a single test case only, you will have a basic framework with you, which has only 1 test case in it. Also, it’s not necessary that you have to add all the components/features onto a single test case. The thumb rule is to create one test case and add the important components and features to it. So, once this basic framework is ready (with the important components), you can start adding other test cases to your framework.
What you saw above was the generic approach that you can follow to create a framework from scratch. Now you would see the exact steps or approach that we will follow here to create our hybrid framework.
1) The first step would be to define a generic folder structure that you would use for your framework. Please note that its not necessary that whatever folder structure you create in the beginning is 100% correct. This is because there might be some scenarios that might have skipped your mind in the beginning. And to accommodate that scenario you might need to alter the folder structure a bit. But most of the times, 80-90% of your folder structure would remain the same way as you had thought of it initially.
2) The next step that you would need to follow is to write the first test case. This should be a plain and simple test case, like the way its written in QTP linear framework.
Note: Many a times, people start with the second step first. That is, they first write the test case and think about the folder structure at some later stage. This approach also works fine. But we suggest you work on folder structure first because when you start thinking about the folder structure in the beginning, you sort of think about how your overall framework would look like. And thinking about that sort of details since the initial stages sometimes help you avoid costly (in terms of time and effort) reworks.
3) After you verify that your test case (written in linear manner) works fine, the next step would be to analyze the code and identify reusable functions. At this step, you would need to introduce the function library and move the reusable functions into it.
4) Next step would be to remove all the hard-coded data from the test case and put it in an excel sheet. You should then write the code to fetch your data from the excel sheets.
5) At this step, you would need to create a batch excel sheet and add a macro or driver script to it. This macro when executed would run your test case (that is added in the batch excel sheet).
6) Now you would need to work on the test results part. You would have to modify your code so that you can store your test results in two different ways – both as summarized results as well as detailed results. You would also need to add a time-stamp mechanism to your result files so that it doesn’t get overwritten.
7) The next step would be to add the auto-email functionality to your framework. At this point, you would have your basic hybrid framework ready that has most of the important features added in.
8) Now, the next step would be to add the remaining test cases in your framework. At this stage, it would not be required to first write the test cases in linear fashion. Since most of the common functions are already in place, you can directly start using those functions when you write the test scripts.
9) The ninth and final step would be to modify some of the code as deemed necessary. This step is important because the initial framework that you created worked well on 1 test case. But when you try to add multiple test cases, you might need to make some additional changes in your code so that all the test cases can run one after the other without any issues.
At this stage, you will have your full fledged hybrid framework up and running. With this, let us now start with our first step.
The folder structure that would be used for this hybrid framework is given below.
Most of the stuff in the folder structure is self explanatory. Let’s quickly go through each one of them.
a) QTP-Hyrbid-Framework folder: This is the parent folder. All the framework code and other artifacts will be stored inside this folder.
b) Batch folder: This is the folder that takes care of the batch execution. The batch excel sheet (which will have the list of all the test cases) and the excel macro will be stored in this folder.
c) DataSheet folder: All your excel data sheets will be stored in this folder.
d) Resources folder: This is just a top-level folder that has many sub-folders inside it.
e) AppSpecific_FunctionLibrary, Generic_FunctionLibrary and Object Repository: These folders will be used to store function libraries and object repositories.
f) ConfigurationFiles folder: This folder will contain the items that would be used to configure the overall framework settings. For example, the settings such as whether to send email or not, or what should be the default wait time etc will be stored in this folder.
g) GenericFiles folder: This folder will be used to store the generic files. For example, if your test cases upload or download some files to/from the application, then those files will be stored in this folder.
h) Results folder: Results folder contains many sub-folders that will be used to store the test results and the error screenshots.
i) TestCases folder: This is the folder where all your QTP test cases will be stored.
Writing the first test script
You have already defined the folder structure and now its time to write your first test script. You would be writing this test script in linear fashion, that is, in the way its done in case of QTP linear framework. This means that all the code will be in a linear, sequential manner. Also at this stage, you would not create any reusable functions. All your test data will also be hard-coded with the test script itself.
While writing the test script, please make sure that you don’t record the script. Use object repository to first add the objects and then write the code in the QTP test case. The test case that you would create first is TC01_CreateOrder. The flow of the test case would be like this –
Once your test case is created, store it in the “TestCases” folder. Also save the object repository in its corresponding location. Below we have given the complete code for create order. The code that you create would look somewhat similar to this.
'Open the flight reservation application SystemUtil.Run "C:\Program Files\HP\QuickTest Professional\samples\flight\app\flight4a.exe" 'Login to the application Dialog("Login").WinEdit("AgentName").Set "anish" Dialog("Login").WinEdit("Password").Set "mercury" Dialog("Login").WinButton("OK").Click 'Verify that login is successful If (Window("FlightReservation").Exist(10)) Then Reporter.ReportEvent micPass, "Login Successful", "Login Successful" Else Reporter.ReportEvent micFail, "Login Unsuccessful", "Login Unsuccessful" End If 'Create a new order - i.e. book a flight ticket Window("FlightReservation").ActiveX("DateOfFlight").Type "010135" Window("FlightReservation").WinComboBox("FlyFrom").Select "Denver" Window("FlightReservation").WinComboBox("FlyTo").Select "Frankfurt" Window("FlightReservation").WinButton("Flights...").Click 'Select the first flight in the list and click OK Window("FlightReservation").Dialog("FlightsTable").WinButton("OK").Click 'Provide name, class and Insert the order (using descriptive programming approach) Window("FlightReservation").WinEdit("attached text:=Name:","nativeclass:=Edit").Set "anish" Window("FlightReservation").WinRadioButton("text:=First").Click Window("FlightReservation").WinButton("text:=&Insert Order").Click wait(8) 'Verify if order is created strOrderNumber = Window("FlightReservation").WinEdit("attached text:=Order No:").GetROProperty("text") If (strOrderNumber <> "") Then Reporter.ReportEvent micPass, "Flight booked successfully", "Order number - " & strOrderNumber Else Reporter.ReportEvent micFail, "Flight not booked", "Flight not booked" End If 'Close the application Window("FlightReservation").Close
Before you move over to the next stage, you have to make sure that whatever you have done till now works fine. So, run the test script that you have created and verify that it executes completely without any issues.
Important note: Please note that, as part of this framework creation process, the basic steps such as adding objects to the object repository, associating function library to the scripts etc would not be explained. We are assuming that you have gone through all the previous articles on the other QTP frameworks and hence you have a good understanding on how these basic things are done. Even if you have directly started with this article, we will assume that you have a basic understanding on how different QTP frameworks work.
Function Library – Adding application independent functions
In the previous article on QTP hybrid framework, we had mentioned that a hybrid framework is created by taking out features from other framework types and implementing them in your framework. This is exactly what you would do next. You would select the features from the other framework types and add them to your framework one by one.
The first feature that you would include in your framework is to add reusable functions, and that too the application independent functions. Now, the first question that you would come to your mind is – what are application dependent functions? Well, as the name suggests, an application independent function is a reusable function that doesn’t depend on your application.
Take QTP click operation as an example. In the above code, you can see that the click operation is used at many places to click on different types of buttons. Now, this click function is not bound to the flight reservation application in any way. So if you replace the flight reservation application with some other application, like the windows calculator, the click button will still function in the same way. As long as you pass the correct object, the click operation will click on the button, be it in the flight reservation application or in the windows calculator.
So, similar to the click operation, there are various other operations like set, type, select etc that do not depend on your application under test. So the first thing that you would do it to replace these QTP operations with your own custom functions. The whole idea here is to replace all (or most of) the QTP operations with your own custom functions.
Why application independent functions are important?
Well, this is another important question that might have come into your minds. When QTP already provides its own functions like click, set, type etc then why do we need to replace them with our custom functions. Well, there are a few reasons as to why we do so –
1) By creating your own functions, you can extend the capability of the operation by adding more features to it. For example, you can write a function called fnButtonClick() where you can first verify if the button exists. Then you add the code to actually click on the button. And finally you can add your custom message which tells that the button has been clicked. In this way, you are extending the normal click operation by adding more operations to it.
2) Another important thing that you can accomplish is custom error handling. If the button that you try to click is not found, QTP will handle the error in the way that you specified. This way, you will have more control on how your framework behaves in error scenarios.
3) You can provide more meaningful names to your custom functions. For example, rather than using an operation called set, you can create your own function that you can name as setValueInTextField(). These sort of function names make more sense than some QTP defined operation names.
4) These custom functions can be used to achieve method overriding. Refer the article on method overriding using RegisterUserFunc for more information about this concept.
Let us now see how to replace the QTP operations with your custom functions.
Replacing QTP operations with application independent functions
Follow the steps given below to replace the QTP operations with your own custom functions.
1) Create a new function library and save it in the Generic_FunctionLibrary folder.
2) Associate the function library with the test script.
3) To replace the set operation with your custom function, add the following code in the function library.
'Registering the user defined functions '================================ ' RegisterUserFunc "WinEdit", "fnSetValueInTextField", "fnSetValue" ' ' ' '================================ 'Function name - fnSetValue 'Description - Set value in a text field '================================ Function fnSetValue(objControl, strValue) On Error Resume Next 'Set the value objControl.Set strValue 'Report out the result If Err.Number = 0 Then Reporter.ReportEvent micPass, "Value - '" & strValue & "' entered in Field - '" & objControl.ToString() & "'", "Passed" End If End Function '================================
4) Come back to the test script and replace the operation set with the custom function name. Please note that if each of the above steps is done correctly, the custom function will be displayed as an option in the intellisense menu.
5) Run the code to see that the test script works perfectly fine with the custom function.
6) Replace all the set operations with the same custom function name.
7) Write custom functions for all other operations and add them in your test script.
8) Once this is done, all the QTP operations in the test script will be replaced by your own custom functions. The test script code should look something like this.
'Open the flight reservation application SystemUtil.Run "C:\Program Files\HP\QuickTest Professional\samples\flight\app\flight4a.exe" 'Login to the application Dialog("Login").WinEdit("AgentName").fnSetValueInTextField "anish" Dialog("Login").WinEdit("Password").fnSetValueInTextField "mercury" Dialog("Login").WinButton("OK").fnWinButtonClick 'Verify that login is successful If (Window("FlightReservation").Exist(10)) Then Reporter.ReportEvent micPass, "Login Successful", "Login Successful" Else Reporter.ReportEvent micFail, "Login Unsuccessful", "Login Unsuccessful" End If 'Create a new order - i.e. book a flight ticket Window("FlightReservation").ActiveX("DateOfFlight").fnTypeValueInActiveXField "010135" Window("FlightReservation").WinComboBox("FlyFrom").fnSelectDropDownValue "Denver" Window("FlightReservation").WinComboBox("FlyTo").fnSelectDropDownValue "Frankfurt" Window("FlightReservation").WinButton("Flights...").fnWinButtonClick 'Select the first flight in the list and click OK Window("FlightReservation").Dialog("FlightsTable").WinButton("OK").fnWinButtonClick 'Provide name, class and insert the order (using descriptive programming approach) Window("FlightReservation").WinEdit("attached text:=Name:","nativeclass:=Edit").fnSetValueInTextField "anish" Window("FlightReservation").WinRadioButton("text:=First").fnRadioButtonClick Window("FlightReservation").WinButton("text:=&Insert Order").fnWinButtonClick wait(8) 'Verify if order is created strOrderNumber = Window("FlightReservation").WinEdit("attached text:=Order No:").GetROProperty("text") If (strOrderNumber <> "") Then Reporter.ReportEvent micPass, "Flight booked successfully", "Order number - " & strOrderNumber Else Reporter.ReportEvent micFail, "Flight not booked", "Flight not booked" End If 'Close the application Window("FlightReservation").fnWindowClose
9) After all the QTP operations are replaced with custom functions, run your test script once again to make sure that everything is OK.
Looking at the test results
At this stage, you have replaced all the QTP operations with your own custom functions. Also, the reporting steps have been added inside the custom functions. So let us now have a look at how the test results would look when you run your customized code.
The below image compares the test results before and after you have implemented your custom functions. Here, you can note that the readability of the test results has increased a lot after the addition of custom functions. Now you should be able to quickly glance at the results and get an idea about what is happening with the script.
One issue with the customized result shown above is that even when you customize the result, its look and feel remains the same. You can try to tweak the CSS a bit, but there is not much that you can do there. Another solution would be to extend this logic by writing the results in an HTML file. You can further add style sheets and CSS to make your result HTML files look more beautiful. You can also add your company logo to get more professionally looking test results. That’s the level of control you get when you use custom functions. And that’s one of the main reasons why the custom functions are important.
Function Library – Adding application specific functions
This section is fairly straightforward and is something that you would have done a lot in QTP modular frameworks. The objective of this section is to analyze your code and see if you can identify some reusable components. Once you have done so, you should then replace the linear code with these reusable functions.
By looking at our code, you can easily figure out that the entire test case can be divided into 3 reusable functions. These are – a) open application and login, b) create order, and c) close application. Create these 3 reusable functions and add them in a separate function library. Since these functions are application specific functions, so you have to save this function library in AppSpecific_FunctionLibray folder. Finally, don’t forget to associate this function library to your test case.
After you have replaced your code with the reusable functions, your test script would look something like this.
fnLogin() fnCreateOrder() fnCloseApplication()
Execute the test case to make sure that the addition of these features didn’t result in any issues. Now you have a hybrid framework in which you have incorporated the features of QTP modular framework.
It is now time to stop this article at this point. This post is already very lengthy, adding more content to it will only complicate the matters. So we will stop it here and take up the other components in the next article. The next article will focus on adding data sheets to the framework. Also, we will have a close look at how you can add the batch execution capability to your framework.
This was all from our end and its time to know what you think about it. Use the comments section and pour in your thoughts on this article.