Overriding QTP’s native reporter
Posted by admin - Jul 7, 2009 Articles, Yaron Assa 1 0 Views : 1021 Receive Updates For This Category
Article Tools
- Print this page
- Add Comment
- Send to Friend
- Last Updated on :
Jul 15, 2011
Background
Over the years, we’ve reviewed and discussed a wide and varied array of replacements and enhancements to QTP’s native reporter: From reporting an hierarchical structure, through parallel export to an HTML file, and all the way up to an overall reporting framework.
All these solutions and workarounds work wonderfully in case you’re just starting to build your automation library, but they are hard to implement in existing projects. If you already have a lot of code that uses the Reporter.ReportEvent command directly, you’re in for a lot of editing and code-tweaking in order to make you code work with the new reporting solution.
If you’re stuck with the latter case, I hope this article will help you implement whichever solution you’d like much more easily. However, you should also learn a valuable lesson from this: Always wrap your common commands in functions. If you had a Report function, you could just change its implementation and have your new reporting solution working in no time.
The Implementation
So, how can you override the native Repoter.Reportevent command? We’ll build a mock Reporter class, and steal QTP’s native reporter place.
First, let’s build our mock class. Basically, it’s a simple class with a single ReportEvent method:
Class clsReporter
Dim oFileReporter
Public Sub ReportEvent (iStatus, sStepName, sDetails)
'Enter the relevant code for your reporting solution
'For example, this reports the event to a text file
oFileReporter.AppendAllText("C:\Log.txt", sStep Name & " - " & sDetails & vbcrlf)
End Sub
Private Sub Class_Initialize
Set oFileReporter = DotNetFactory("System.IO.File")
End Sub
End Class
This specific class reports to a text file, but the ReportEvent sub can do anything you’d like it to do – call ReporterManager, report to excel, print out message boxes, or do all of these at once.
Now, for the important part – in order to override QTP’s native reporter, place this class in an external library file, and attach it to your test. Then, add the following code at the top of the file (outside the class):
Public Reporter
Set Reporter = New clsReporter
This will effectively cause all Reporter.ReportEvent commands in library files to funnel back to our custom class, and execute our very own report implementation.
An overall solution
As noted above, this only works for reporter calls made in external library files. QTP’s script management makes our little trick take precedent over QTP objecta in the external libraries, but it doesn’t work for code written directly within actions. In order to override the Reporter object within the actions, we’ll have to add the following function to our external library file, just above the class definition:
Function GetReporter
Set GetReporter = Reporter
End Function
And use the following code as the topmost command in each of our actions:
Set Reporter = GetReporter
This will cause the following chain reaction:
1. When the test begins to run, the external library files are executed. This causes our custom class to override QTP’s native reporter.
2. When a test enters an action, it create a new script “bubble”, and in that bubble, re-overrides our custom reporter with QTP’s native reporter.
3. In order to fix the bubble, we run a command within the action, which fetches the custom reporter from the library file (via the GetReporter funciton), and overrides the local reporter object with in.
4. Now Reporter.ReportEvent commands performed within the action will funnel to our custom reporter, even though it was defined in an external file.
Notice however, that this workaround have a major flaw – what if you still want to report to the native reporter (in parallel to your own custom reporter)? we can’t simply call the Reporter.ReportEvent command – we’ve just spent a lot of effort to override it!
There is a partial workaround for this problem as well, but it’s way more complex than this article’s scope.
Update: hsupadrasta has come up with a nice simple workaround for the above problem.
Just add this code on at the top of your actions:
'Save the native reporter to a global variable
ExecuteGlobal "Dim oNativeReporter"
Set oNativeReporter = Reporter
'Now we can overrun the reproter with our class
Execute "Dim Reporter"
Set Reporter = GetReporter
And now your could still use the native reporter via the oNativeReporter variable.
Thanks hsupadrasta for this great tweak!
Putting it all together
Since I’ve explained the different components of the workaround separately, it may come across as overly complex, but in fact, it’s quite simple. Here’s the entire code combined (goes within an external code library):
'Override it with our custom class
Dim Reporter
Set Reporter = New clsReporter
'Define a funnel function to be called from the test actions
Public Function GetReporter
Set GetReporter = Reporter
End Function
'Class definition
'In the example, our class just reporter to a text file
Class clsReporter
Dim oFileReporter
Public Sub ReportEvent(iStatus, sStepName, sDetails)
oFileReporter.AppendAllText "c:\log.txt", sStepName & " - " & sDetails & vbcrlf
End Sub
Private Sub Class_Initialize
Set oFIleReporter = DotNetFactory("System.IO.File")
End Sub
End Class
And this code at the top of each action:
Dim Reporter
Set Reporter = GetReporter
I hope this would help you make a smoother transition into your new reporting framework.



xydlerocks
Jan 24, 2012
Do you really feel that QTP Native reporter is limited for projects?
I feel that we have neglected the Native reporter’s capabilities since QTP Version 9.5