{"id":2090,"date":"2013-08-03T06:03:51","date_gmt":"2013-08-03T00:33:51","guid":{"rendered":"http:\/\/www.automationrepository.com\/?p=2090"},"modified":"2013-08-03T06:04:18","modified_gmt":"2013-08-03T00:34:18","slug":"designing-hybrid-framework-in-qtp-part-2","status":"publish","type":"post","link":"https:\/\/www.automationrepository.com\/wordpress\/2013\/08\/designing-hybrid-framework-in-qtp-part-2\/","title":{"rendered":"Designing Hybrid Framework in QTP &#8211; Part 2"},"content":{"rendered":"<p>Continued from previous article &#8211; <a title=\"Designing Hybrid Framework in QTP \u2013 Part 1\" href=\"http:\/\/www.automationrepository.com\/2013\/07\/designing-hybrid-framework-in-qtp-part-1\/\" target=\"_blank\">Designing Hybrid Framework in QTP (Part 1)<\/a>. 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 <!--more-->and then would build upon it by incorporating more features to it.<\/p>\n<p><span><br \/>\n<\/span><\/p>\n<h3>Topics that will be covered in this article<\/h3>\n<p>In this article, we will cover the following aspects of the hybrid framework &#8211;<\/p>\n<p><strong>a)<\/strong> Identifying the test cases that will be automated as part of this framework<\/p>\n<p><strong>b)<\/strong> The plan or approach as to how the framework will be created<\/p>\n<p><strong>c)<\/strong> Folder structure and writing the first test case<\/p>\n<p><strong>d)<\/strong> Applying the modular framework features in this hybrid framework<\/p>\n<p><span><br \/>\n<\/span><\/p>\n<h3>Test Cases that will be automated<\/h3>\n<p>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.<br \/>\n<span><br \/>\n<\/span><br \/>\n<strong>1) TC01_CreateOrder:<\/strong> The flow of this test case would be to login to the application, create an order and then logout<br \/>\n<span><br \/>\n<\/span><br \/>\n<strong>2) TC02_CreateAndUpdateOrder:<\/strong> For this test case, the flow would be: login &gt;&gt; create order &gt;&gt; search order &gt;&gt; logout<br \/>\n<span><br \/>\n<\/span><br \/>\n<strong>3) TC03_CreateAndDeleteOrder:<\/strong> Here, the flow of the test case would be like this: login &gt;&gt; create order &gt;&gt; search order &gt;&gt; delete order &gt;&gt; logout<\/p>\n<p><span><br \/>\n<\/span><\/p>\n<h3>Basic approach to create the hybrid framework<\/h3>\n<p>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&#8217;t go on doing random stuff and assume that the components and features would somehow get linked together at the end.<br \/>\n<span><br \/>\n<\/span><br \/>\nThe 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.<br \/>\n<span><br \/>\n<\/span><br \/>\nBy 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&#8217;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.<br \/>\n<span><br \/>\n<\/span><br \/>\nWhat 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.<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" title=\"Approach to create Hybrid Framework in QTP\" alt=\"Approach to create Hybrid Framework in QTP\" src=\"https:\/\/www.automationrepository.com\/wordpress\/wp-content\/uploads\/ar\/approach-to-create-hybrid-framework.png\" width=\"401\" height=\"441\" \/><\/p>\n<p><em> <\/em><br \/>\n<strong>1) <\/strong>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.<br \/>\n<span><br \/>\n<\/span><br \/>\n<strong>2) <\/strong>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 <a title=\"QTP Linear Framework \u2013 Complete Reference with Example\" href=\"http:\/\/www.automationrepository.com\/2012\/04\/qtp-framework-tutorial-qtp-linear-framework\/\" target=\"_blank\">QTP linear framework<\/a>.<br \/>\n<span><br \/>\n<\/span><br \/>\n<span style=\"text-decoration: underline;\"><strong>Note:<\/strong><\/span> 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.<br \/>\n<span><br \/>\n<\/span><br \/>\n<strong>3)<\/strong> 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.<br \/>\n<span><br \/>\n<\/span><br \/>\n<strong>4)<\/strong> 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.<br \/>\n<span><br \/>\n<\/span><br \/>\n<strong>5)<\/strong> 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).<br \/>\n<span><br \/>\n<\/span><br \/>\n<strong>6)<\/strong> 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 &#8211; 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&#8217;t get overwritten.<br \/>\n<span><br \/>\n<\/span><br \/>\n<strong>7)<\/strong> 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.<br \/>\n<span><br \/>\n<\/span><br \/>\n<strong>8)<\/strong> 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.<br \/>\n<span><br \/>\n<\/span><br \/>\n<strong>9)<\/strong> 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.<br \/>\n<span><br \/>\n<\/span><br \/>\n<strong> At this stage, you will have your full fledged hybrid framework up and running.<\/strong> With this, let us now start with our first step.<\/p>\n<p><span><br \/>\n<\/span><\/p>\n<h3>Folder structure<\/h3>\n<p>The folder structure that would be used for this hybrid framework is given below.<\/p>\n<p style=\"text-align: center;\"><span style=\"color: #ff0000;\"><strong><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" title=\"Hybrid Framework in QTP - Folder Structure\" alt=\"Hybrid Framework in QTP - Folder Structure\" src=\"https:\/\/www.automationrepository.com\/wordpress\/wp-content\/uploads\/ar\/qtp-hybrid-framework-folder-structure.png\" width=\"244\" height=\"309\" \/><\/strong><\/span><\/p>\n<p>Most of the stuff in the folder structure is self explanatory. Let&#8217;s quickly go through each one of them.<\/p>\n<p><strong>a) <\/strong>QTP-Hyrbid-Framework folder: This is the parent folder. All the framework code and other artifacts will be stored inside this folder.<\/p>\n<p><strong>b)<\/strong> 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.<\/p>\n<p><strong>c)<\/strong> DataSheet folder: All your excel data sheets will be stored in this folder.<\/p>\n<p><strong>d)<\/strong> Resources folder: This is just a top-level folder that has many sub-folders inside it.<\/p>\n<p><strong>e)<\/strong> AppSpecific_FunctionLibrary, Generic_FunctionLibrary and Object Repository: These folders will be used to store function libraries and object repositories.<\/p>\n<p><strong>f)<\/strong> 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.<\/p>\n<p><strong>g)<\/strong> 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.<\/p>\n<p><strong>h)<\/strong> Results folder: Results folder contains many sub-folders that will be used to store the test results and the error screenshots.<\/p>\n<p><strong>i)<\/strong> TestCases folder: This is the folder where all your QTP test cases will be stored.<\/p>\n<p><span><br \/>\n<\/span><\/p>\n<h3>Writing the first test script<\/h3>\n<p>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 <a title=\"QTP Linear Framework \u2013 Complete Reference with Example\" href=\"http:\/\/www.automationrepository.com\/2012\/04\/qtp-framework-tutorial-qtp-linear-framework\/\" target=\"_blank\">QTP linear framework<\/a>. 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.<br \/>\n<span><br \/>\n<\/span><br \/>\nWhile writing the test script, please make sure that you don&#8217;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 <strong>TC01_CreateOrder<\/strong>. The flow of the test case would be like this &#8211;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" alt=\"QTP Hybrid Framework - Create Order Test Case Flow\" src=\"https:\/\/www.automationrepository.com\/wordpress\/wp-content\/uploads\/ar\/hybrid-framework-test-case-flow.png\" width=\"445\" height=\"320\" \/><\/p>\n<p><em> <\/em><br \/>\nOnce your test case is created, store it in the &#8220;<strong>TestCases<\/strong>&#8221; 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.<br \/>\n<em> <\/em><\/p>\n<pre class=\"brush: vb; title: ; notranslate\" title=\"\">\r\n'Open the flight reservation application\r\nSystemUtil.Run &quot;C:\\Program Files\\HP\\QuickTest Professional\\samples\\flight\\app\\flight4a.exe&quot;\r\n\r\n'Login to the application\r\nDialog(&quot;Login&quot;).WinEdit(&quot;AgentName&quot;).Set &quot;anish&quot;\r\nDialog(&quot;Login&quot;).WinEdit(&quot;Password&quot;).Set &quot;mercury&quot;\r\nDialog(&quot;Login&quot;).WinButton(&quot;OK&quot;).Click\r\n\r\n'Verify that login is successful\r\nIf (Window(&quot;FlightReservation&quot;).Exist(10)) Then\r\n\tReporter.ReportEvent micPass, &quot;Login Successful&quot;, &quot;Login Successful&quot;\r\nElse\r\n\tReporter.ReportEvent micFail, &quot;Login Unsuccessful&quot;, &quot;Login Unsuccessful&quot;\r\nEnd If\r\n\r\n'Create a new order - i.e. book a flight ticket\r\nWindow(&quot;FlightReservation&quot;).ActiveX(&quot;DateOfFlight&quot;).Type &quot;010135&quot;\r\nWindow(&quot;FlightReservation&quot;).WinComboBox(&quot;FlyFrom&quot;).Select &quot;Denver&quot;\r\nWindow(&quot;FlightReservation&quot;).WinComboBox(&quot;FlyTo&quot;).Select &quot;Frankfurt&quot;\r\nWindow(&quot;FlightReservation&quot;).WinButton(&quot;Flights...&quot;).Click\r\n\r\n'Select the first flight in the list and click OK\r\nWindow(&quot;FlightReservation&quot;).Dialog(&quot;FlightsTable&quot;).WinButton(&quot;OK&quot;).Click\r\n\r\n'Provide name, class and Insert the order (using descriptive programming approach)\r\nWindow(&quot;FlightReservation&quot;).WinEdit(&quot;attached text:=Name:&quot;,&quot;nativeclass:=Edit&quot;).Set &quot;anish&quot;\r\nWindow(&quot;FlightReservation&quot;).WinRadioButton(&quot;text:=First&quot;).Click\r\nWindow(&quot;FlightReservation&quot;).WinButton(&quot;text:=&amp;Insert Order&quot;).Click\r\nwait(8)\r\n\r\n'Verify if order is created\r\nstrOrderNumber = Window(&quot;FlightReservation&quot;).WinEdit(&quot;attached text:=Order No:&quot;).GetROProperty(&quot;text&quot;)\r\nIf (strOrderNumber &lt;&gt; &quot;&quot;) Then\r\n\tReporter.ReportEvent micPass, &quot;Flight booked successfully&quot;, &quot;Order number - &quot; &amp; strOrderNumber\r\nElse\r\n\tReporter.ReportEvent micFail, &quot;Flight not booked&quot;, &quot;Flight not booked&quot;\r\nEnd If\r\n\r\n'Close the application\r\nWindow(&quot;FlightReservation&quot;).Close\r\n<\/pre>\n<p><em> <\/em><br \/>\nBefore 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.<br \/>\n<span><br \/>\n<\/span><br \/>\n<span style=\"text-decoration: underline;\"><strong>Important note:<\/strong><\/span> 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.<\/p>\n<p><span><br \/>\n<\/span><\/p>\n<h3>Function Library &#8211; Adding application independent functions<\/h3>\n<p>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.<br \/>\n<span><br \/>\n<\/span><br \/>\nThe 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 &#8211; what are application dependent functions? Well, as the name suggests, an application independent function is a reusable function that doesn&#8217;t depend on your application.<br \/>\n<span><br \/>\n<\/span><br \/>\nTake 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.<br \/>\n<span><br \/>\n<\/span><br \/>\nSo, 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.<\/p>\n<p><span><br \/>\n<\/span><\/p>\n<h3>Why application independent functions are important?<\/h3>\n<p>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 &#8211;<br \/>\n<span><br \/>\n<\/span><br \/>\n<strong>1)<\/strong> 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.<br \/>\n<span><br \/>\n<\/span><br \/>\n<strong>2)<\/strong> 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.<br \/>\n<span><br \/>\n<\/span><br \/>\n<strong>3)<\/strong> 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.<br \/>\n<span><br \/>\n<\/span><br \/>\n<strong>4)<\/strong> These custom functions can be used to achieve method overriding. Refer the article on <a title=\"How to achieve Method Overriding &amp; Reuse using RegisterUserFunc in QTP\" href=\"http:\/\/www.automationrepository.com\/2011\/12\/how-to-achieve-method-overriding-and-reuse-using-registeruserfunc-in-qtp\/\" target=\"_blank\"><strong>method overriding using RegisterUserFunc<\/strong><\/a> for more information about this concept.<\/p>\n<p>Let us now see how to replace the QTP operations with your custom functions.<\/p>\n<p><span><br \/>\n<\/span><\/p>\n<h3>Replacing QTP operations with application independent functions<\/h3>\n<p>Follow the steps given below to replace the QTP operations with your own custom functions.<\/p>\n<p><strong>1) <\/strong>Create a new function library and save it in the<strong> Generic_FunctionLibrary<\/strong> folder.<\/p>\n<p><strong>2) <\/strong>Associate the function library with the test script.<\/p>\n<p><strong>3)<\/strong> To replace the set operation with your custom function, add the following code in the function library.<\/p>\n<pre class=\"brush: vb; title: ; notranslate\" title=\"\">\r\n'Registering the user defined functions\r\n'================================\r\n'\r\nRegisterUserFunc &quot;WinEdit&quot;, &quot;fnSetValueInTextField&quot;, &quot;fnSetValue&quot;\r\n'\r\n'\r\n'\r\n'================================\r\n'Function name - fnSetValue\r\n'Description - Set value in a text field\r\n'================================\r\nFunction fnSetValue(objControl, strValue)\r\n\r\nOn Error Resume Next\r\n\r\n'Set the value\r\nobjControl.Set strValue\r\n\r\n'Report out the result\r\nIf Err.Number = 0 Then\r\nReporter.ReportEvent micPass, &quot;Value - '&quot; &amp; strValue &amp; &quot;' entered in Field - '&quot; &amp; objControl.ToString() &amp; &quot;'&quot;, &quot;Passed&quot;\r\nEnd If\r\n\r\nEnd Function\r\n'================================\r\n<\/pre>\n<p><em> <\/em><br \/>\n<strong>4)<\/strong> 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.<\/p>\n<pre class=\"brush: vb; title: ; notranslate\" title=\"\">\r\nDialog(&quot;Login&quot;).WinEdit(&quot;AgentName&quot;).fnSetValueInTextField &quot;anish&quot;\r\n<\/pre>\n<p><em> <\/em><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" alt=\"QTP Hybrid Framework - custom function displayed in intellisense menu\" src=\"https:\/\/www.automationrepository.com\/wordpress\/wp-content\/uploads\/ar\/intellisense-menu-displays-user-defined-function.png\" width=\"469\" height=\"322\" \/><br \/>\n<em> <\/em><\/p>\n<p><strong>5)<\/strong> Run the code to see that the test script works perfectly fine with the custom function.<\/p>\n<p><strong>6)<\/strong> Replace all the set operations with the same custom function name.<\/p>\n<p><strong>7)<\/strong> Write custom functions for all other operations and add them in your test script.<\/p>\n<p><strong>8)<\/strong> 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.<\/p>\n<pre class=\"brush: vb; title: ; notranslate\" title=\"\">\r\n'Open the flight reservation application\r\nSystemUtil.Run &quot;C:\\Program Files\\HP\\QuickTest Professional\\samples\\flight\\app\\flight4a.exe&quot;\r\n\r\n'Login to the application\r\nDialog(&quot;Login&quot;).WinEdit(&quot;AgentName&quot;).fnSetValueInTextField &quot;anish&quot;\r\nDialog(&quot;Login&quot;).WinEdit(&quot;Password&quot;).fnSetValueInTextField &quot;mercury&quot;\r\nDialog(&quot;Login&quot;).WinButton(&quot;OK&quot;).fnWinButtonClick\r\n\r\n'Verify that login is successful\r\nIf (Window(&quot;FlightReservation&quot;).Exist(10)) Then\r\nReporter.ReportEvent micPass, &quot;Login Successful&quot;, &quot;Login Successful&quot;\r\nElse\r\nReporter.ReportEvent micFail, &quot;Login Unsuccessful&quot;, &quot;Login Unsuccessful&quot;\r\nEnd If\r\n\r\n'Create a new order - i.e. book a flight ticket\r\nWindow(&quot;FlightReservation&quot;).ActiveX(&quot;DateOfFlight&quot;).fnTypeValueInActiveXField &quot;010135&quot;\r\nWindow(&quot;FlightReservation&quot;).WinComboBox(&quot;FlyFrom&quot;).fnSelectDropDownValue &quot;Denver&quot;\r\nWindow(&quot;FlightReservation&quot;).WinComboBox(&quot;FlyTo&quot;).fnSelectDropDownValue &quot;Frankfurt&quot;\r\nWindow(&quot;FlightReservation&quot;).WinButton(&quot;Flights...&quot;).fnWinButtonClick\r\n\r\n'Select the first flight in the list and click OK\r\nWindow(&quot;FlightReservation&quot;).Dialog(&quot;FlightsTable&quot;).WinButton(&quot;OK&quot;).fnWinButtonClick\r\n\r\n'Provide name, class and insert the order (using descriptive programming approach)\r\nWindow(&quot;FlightReservation&quot;).WinEdit(&quot;attached text:=Name:&quot;,&quot;nativeclass:=Edit&quot;).fnSetValueInTextField &quot;anish&quot;\r\nWindow(&quot;FlightReservation&quot;).WinRadioButton(&quot;text:=First&quot;).fnRadioButtonClick\r\nWindow(&quot;FlightReservation&quot;).WinButton(&quot;text:=&amp;Insert Order&quot;).fnWinButtonClick\r\nwait(8)\r\n\r\n'Verify if order is created\r\nstrOrderNumber = Window(&quot;FlightReservation&quot;).WinEdit(&quot;attached text:=Order No:&quot;).GetROProperty(&quot;text&quot;)\r\nIf (strOrderNumber &lt;&gt; &quot;&quot;) Then\r\nReporter.ReportEvent micPass, &quot;Flight booked successfully&quot;, &quot;Order number - &quot; &amp; strOrderNumber\r\nElse\r\nReporter.ReportEvent micFail, &quot;Flight not booked&quot;, &quot;Flight not booked&quot;\r\nEnd If\r\n\r\n'Close the application\r\nWindow(&quot;FlightReservation&quot;).fnWindowClose\r\n<\/pre>\n<p><em> <\/em><br \/>\n<strong>9)<\/strong> After all the QTP operations are replaced with custom functions, run your test script once again to make sure that everything is OK.<\/p>\n<p><span><br \/>\n<\/span><\/p>\n<h3>Looking at the test results<\/h3>\n<p>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.<br \/>\n<span><br \/>\n<\/span><br \/>\nThe 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.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" alt=\"QTP Hybrid Framework - customized test run results\" src=\"https:\/\/www.automationrepository.com\/wordpress\/wp-content\/uploads\/ar\/customized-test-run-results.png\" width=\"591\" height=\"378\" \/><\/p>\n<p><em> <\/em><br \/>\nOne 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&#8217;s the level of control you get when you use custom functions. And that&#8217;s one of the main reasons why the custom functions are important.<\/p>\n<p><span><br \/>\n<\/span><\/p>\n<h3>Function Library &#8211; Adding application specific functions<\/h3>\n<p>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.<br \/>\n<span><br \/>\n<\/span><br \/>\nBy looking at our code, you can easily figure out that the entire test case can be divided into 3 reusable functions. These are &#8211; <strong>a) <\/strong>open application and login, <strong>b) <\/strong>create order, and <strong>c)<\/strong> 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 <strong>AppSpecific_FunctionLibray<\/strong> folder. Finally, don&#8217;t forget to associate this function library to your test case.<br \/>\n<span><br \/>\n<\/span><br \/>\nAfter you have replaced your code with the reusable functions, your test script would look something like this.<\/p>\n<pre class=\"brush: vb; title: ; notranslate\" title=\"\">\r\nfnLogin()\r\nfnCreateOrder()\r\nfnCloseApplication()\r\n<\/pre>\n<p>Execute the test case to make sure that the addition of these features didn&#8217;t result in any issues. Now you have a hybrid framework in which you have incorporated the features of QTP modular framework.<br \/>\n<span><br \/>\n<\/span><br \/>\nIt 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.<br \/>\n<span><br \/>\n<\/span><br \/>\n<strong>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.<\/strong><\/p>\n<p><span><br \/>\n<\/span><\/p>\n<div style=\"font-family: Verdana,sans-serif; border: 1px solid #C8B560; padding: 3mm; background: #FFF8C6; text-align: center;\">\n<p><strong>If you enjoyed this article, you can join our blog to get new articles delivered directly in your inbox.<\/strong><\/p>\n<form style=\"text-align: center;\" action=\"http:\/\/feedburner.google.com\/fb\/a\/mailverify\" method=\"post\" target=\"popupwindow\" onsubmit=\"window.open('http:\/\/feedburner.google.com\/fb\/a\/mailverify?uri=automationrepository\/feeds', 'popupwindow', 'scrollbars=yes,width=550,height=520');return true\"><input style=\"width: 160px; height: 20px;\" type=\"text\" value=\"Enter Your Email Address\" onfocus=\"if (this.value == 'Enter Your Email Address') {this.value = '';}\" onblur=\"if (this.value == '') {this.value = 'Enter Your Email Address';}\" \/> <input type=\"hidden\" name=\"uri\" value=\"automationrepository\/feeds\" \/> <input type=\"hidden\" name=\"loc\" value=\"en_US\" \/> <input type=\"submit\" value=\"Join Us\" \/><\/p>\n<p style=\"text-align: justify;\">\n<\/form>\n<\/div>\n<p style=\"border: 1px solid #C38EC7; padding: 3mm; background: #EBDDE2;\"><strong>Visit <a title=\"QTP Frameworks \u2013 An Introduction\" href=\"http:\/\/www.automationrepository.com\/2012\/03\/qtp-framework-types-an-introduction\/\">QTP Frameworks<\/a> Main Page for more articles on QTP Frameworks<\/strong>. You can also visit our <a title=\"QTP Tutorials\" href=\"http:\/\/www.automationrepository.com\/tutorials-for-qtp-beginners\/\" target=\"_blank\">QTP Tutorials<\/a> page for detailed QTP Tutorials.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Continued from previous article &#8211; 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<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,97],"tags":[102],"class_list":["post-2090","post","type-post","status-publish","format-standard","hentry","category-advanced-concepts","category-qtp-framework","tag-qtp-hybrid-framework"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Designing Hybrid Framework in QTP - Part 2 - XX<\/title>\n<meta name=\"description\" content=\"This article describes the approach you can use to create a Hybrid Framework in QTP. Also, see how modular framework features are added to this framework\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.automationrepository.com\/wordpress\/2013\/08\/designing-hybrid-framework-in-qtp-part-2\/\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Anish Pillai\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"19 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.automationrepository.com\/wordpress\/2013\/08\/designing-hybrid-framework-in-qtp-part-2\/\",\"url\":\"https:\/\/www.automationrepository.com\/wordpress\/2013\/08\/designing-hybrid-framework-in-qtp-part-2\/\",\"name\":\"Designing Hybrid Framework in QTP - Part 2 - XX\",\"isPartOf\":{\"@id\":\"https:\/\/www.automationrepository.com\/wordpress\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.automationrepository.com\/wordpress\/2013\/08\/designing-hybrid-framework-in-qtp-part-2\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.automationrepository.com\/wordpress\/2013\/08\/designing-hybrid-framework-in-qtp-part-2\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.automationrepository.com\/wordpress\/wp-content\/uploads\/ar\/approach-to-create-hybrid-framework.png\",\"datePublished\":\"2013-08-03T00:33:51+00:00\",\"dateModified\":\"2013-08-03T00:34:18+00:00\",\"author\":{\"@id\":\"https:\/\/www.automationrepository.com\/wordpress\/#\/schema\/person\/7a35710e1ce89e5fb481be88fcd6cd20\"},\"description\":\"This article describes the approach you can use to create a Hybrid Framework in QTP. Also, see how modular framework features are added to this framework\",\"breadcrumb\":{\"@id\":\"https:\/\/www.automationrepository.com\/wordpress\/2013\/08\/designing-hybrid-framework-in-qtp-part-2\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.automationrepository.com\/wordpress\/2013\/08\/designing-hybrid-framework-in-qtp-part-2\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.automationrepository.com\/wordpress\/2013\/08\/designing-hybrid-framework-in-qtp-part-2\/#primaryimage\",\"url\":\"https:\/\/www.automationrepository.com\/wordpress\/wp-content\/uploads\/ar\/approach-to-create-hybrid-framework.png\",\"contentUrl\":\"https:\/\/www.automationrepository.com\/wordpress\/wp-content\/uploads\/ar\/approach-to-create-hybrid-framework.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.automationrepository.com\/wordpress\/2013\/08\/designing-hybrid-framework-in-qtp-part-2\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.automationrepository.com\/wordpress\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Designing Hybrid Framework in QTP &#8211; Part 2\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.automationrepository.com\/wordpress\/#website\",\"url\":\"https:\/\/www.automationrepository.com\/wordpress\/\",\"name\":\"XX\",\"description\":\"\\r\\nasas\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.automationrepository.com\/wordpress\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.automationrepository.com\/wordpress\/#\/schema\/person\/7a35710e1ce89e5fb481be88fcd6cd20\",\"name\":\"Anish Pillai\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.automationrepository.com\/wordpress\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/8aa984de2295c3c4078fa48f6ba5d91e7c849b1a27a11dca24c6f11dd673ba14?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/8aa984de2295c3c4078fa48f6ba5d91e7c849b1a27a11dca24c6f11dd673ba14?s=96&d=mm&r=g\",\"caption\":\"Anish Pillai\"},\"description\":\"Find more about Anish Pillai on Google+\",\"sameAs\":[\"http:\/\/www.automationrepository.com\"],\"url\":\"https:\/\/www.automationrepository.com\/wordpress\/author\/anish\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Designing Hybrid Framework in QTP - Part 2 - XX","description":"This article describes the approach you can use to create a Hybrid Framework in QTP. Also, see how modular framework features are added to this framework","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.automationrepository.com\/wordpress\/2013\/08\/designing-hybrid-framework-in-qtp-part-2\/","twitter_misc":{"Written by":"Anish Pillai","Est. reading time":"19 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.automationrepository.com\/wordpress\/2013\/08\/designing-hybrid-framework-in-qtp-part-2\/","url":"https:\/\/www.automationrepository.com\/wordpress\/2013\/08\/designing-hybrid-framework-in-qtp-part-2\/","name":"Designing Hybrid Framework in QTP - Part 2 - XX","isPartOf":{"@id":"https:\/\/www.automationrepository.com\/wordpress\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.automationrepository.com\/wordpress\/2013\/08\/designing-hybrid-framework-in-qtp-part-2\/#primaryimage"},"image":{"@id":"https:\/\/www.automationrepository.com\/wordpress\/2013\/08\/designing-hybrid-framework-in-qtp-part-2\/#primaryimage"},"thumbnailUrl":"https:\/\/www.automationrepository.com\/wordpress\/wp-content\/uploads\/ar\/approach-to-create-hybrid-framework.png","datePublished":"2013-08-03T00:33:51+00:00","dateModified":"2013-08-03T00:34:18+00:00","author":{"@id":"https:\/\/www.automationrepository.com\/wordpress\/#\/schema\/person\/7a35710e1ce89e5fb481be88fcd6cd20"},"description":"This article describes the approach you can use to create a Hybrid Framework in QTP. Also, see how modular framework features are added to this framework","breadcrumb":{"@id":"https:\/\/www.automationrepository.com\/wordpress\/2013\/08\/designing-hybrid-framework-in-qtp-part-2\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.automationrepository.com\/wordpress\/2013\/08\/designing-hybrid-framework-in-qtp-part-2\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.automationrepository.com\/wordpress\/2013\/08\/designing-hybrid-framework-in-qtp-part-2\/#primaryimage","url":"https:\/\/www.automationrepository.com\/wordpress\/wp-content\/uploads\/ar\/approach-to-create-hybrid-framework.png","contentUrl":"https:\/\/www.automationrepository.com\/wordpress\/wp-content\/uploads\/ar\/approach-to-create-hybrid-framework.png"},{"@type":"BreadcrumbList","@id":"https:\/\/www.automationrepository.com\/wordpress\/2013\/08\/designing-hybrid-framework-in-qtp-part-2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.automationrepository.com\/wordpress\/"},{"@type":"ListItem","position":2,"name":"Designing Hybrid Framework in QTP &#8211; Part 2"}]},{"@type":"WebSite","@id":"https:\/\/www.automationrepository.com\/wordpress\/#website","url":"https:\/\/www.automationrepository.com\/wordpress\/","name":"XX","description":"\r\nasas","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.automationrepository.com\/wordpress\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.automationrepository.com\/wordpress\/#\/schema\/person\/7a35710e1ce89e5fb481be88fcd6cd20","name":"Anish Pillai","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.automationrepository.com\/wordpress\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/8aa984de2295c3c4078fa48f6ba5d91e7c849b1a27a11dca24c6f11dd673ba14?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8aa984de2295c3c4078fa48f6ba5d91e7c849b1a27a11dca24c6f11dd673ba14?s=96&d=mm&r=g","caption":"Anish Pillai"},"description":"Find more about Anish Pillai on Google+","sameAs":["http:\/\/www.automationrepository.com"],"url":"https:\/\/www.automationrepository.com\/wordpress\/author\/anish\/"}]}},"_links":{"self":[{"href":"https:\/\/www.automationrepository.com\/wordpress\/wp-json\/wp\/v2\/posts\/2090","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.automationrepository.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.automationrepository.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.automationrepository.com\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.automationrepository.com\/wordpress\/wp-json\/wp\/v2\/comments?post=2090"}],"version-history":[{"count":15,"href":"https:\/\/www.automationrepository.com\/wordpress\/wp-json\/wp\/v2\/posts\/2090\/revisions"}],"predecessor-version":[{"id":2104,"href":"https:\/\/www.automationrepository.com\/wordpress\/wp-json\/wp\/v2\/posts\/2090\/revisions\/2104"}],"wp:attachment":[{"href":"https:\/\/www.automationrepository.com\/wordpress\/wp-json\/wp\/v2\/media?parent=2090"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.automationrepository.com\/wordpress\/wp-json\/wp\/v2\/categories?post=2090"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.automationrepository.com\/wordpress\/wp-json\/wp\/v2\/tags?post=2090"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}