Solution: How to override the QTP Reporter class with your own

Here are the reasons why I override the Reporter class.

  1. Working with Adobe Flex, QTP crashes a lot. It would be nice to view the result status in a flat file format rather than in a broken xml file format
  2. If you don’t know which particular line is failing, it would be nice if we could pause the script on *any* fails …. All you need to so is, put a break point in the class which is in the CustomReporter.txt
  3. etc

Here is the library which we are using for past few years and hope they would work for you as well. I also attached as CustomReporter.txt.

 

 

'********************************************************************************************************************************************************
'# Description:    How to override the Reporter class with your own
'#       
'# Note:   Here is how to utilize & test this Custom Reporter Class
'#       1. Create a new script
'#       2. Associate this library (CustomReporter.txt)
'#       3. For each QTP Action script (i.e. Action1 ), add the follwoing 2 lines of code in the beginning of the Action
'#           Execute "Dim Reporter"
'#           Set Reporter = GetReporter
'#       4. Add a reporter.ReportEvent .... statement and run the script
'#       5. Custom log file will be found inside your result folder (i.e. C:\temp\MyScript\res1\log.txt)   
'#       
'# Created By:   Kelvin Fung
'********************************************************************************************************************************************************
'---------------------------
'Save the QTP Built-in reporter to a global object variable using ExecuteGlobal keyword to avoid compiler issue/err
'---------------------------
ExecuteGlobal "Dim goBuiltInReporter" 'go = Global Object
Set goBuiltInReporter = Reporter

'---------------------------
'Override the Built-in Reporter object with our custom class (i.e. ccReporter), use Execute keyword to trick the compiler to
'executie this statement after saving the built-in Reporter object to goBuiltInReporter
'---------------------------
Execute "Dim Reporter"
Set Reporter = New ccReporter

'--------------------------------------------------------------------------------
'This function will be called from your script to retrieve the 'Reporter' object
'-------------------------------------------------------------------------------
Public Function GetReporter   
  Set GetReporter = Reporter
End Function

''-------------------------------------------------------------------------------
'Here is the Custom Class Reporter definition
''-------------------------------------------------------------------------------
Class ccReporter
 Dim Filter
 Dim FilterEx
 Dim ReportPath
 Dim RunStatus
 Private m_oFSO
 Private m_oTextStream
 private m_sLogFilePath
 private m_NodeName
 'This is a custom Run status, testers could get & set this status freely. The purpose of this var is for testers
 'who would like to track the run status in a block of codes whether it encounters fails or not
 private m_CurrentRunStatus

 'Add custom reporting capabilities to ReportEvent()
 Public Sub ReportEvent(iStatus, sStepName, sDetails)         
     Dim sData, sStatus
  
  'Custom Reporting - output info to a log file
  'sStatus = "Unknown"
  Select Case iStatus
   Case 0
    sStatus = "Pass"
   Case 1
    sStatus = "Fail"
   Case 2
    sStatus = "Done"
   Case 3
    sStatus = "Warning"
   Case 4
    sStatus = "Info"
   Case Else
    sStatus = "Unknown(" & iStatus & ")"
  End Select

  'Custom Reporting - output info to a log file
  sData = Date & Chr(9) & time & Chr(9) & sStatus & Chr(9) & "[STEP]" & sStepName & ", [DETAIL]" & sDetails '& vbcrlf  
  m_oTextStream.WriteLine sData

  'Update the custom Run Status info
  m_CurrentRunStatus = iStatus
  
  'Maintain the built-in capabilities
  goBuiltInReporter.ReportEvent iStatus, sStepName, sDetails
 End Sub

 'Add custom reporting capabilities to LogEvent()
 Public Function LogEvent(et, pDescription, ParentId)         
  Dim intContext, NodeName, NodeDetail, sData

  'Retrieve Node name & detail info from the given pDescription
  NodeName = pDescription("PlainTextNodeName")
  NodeDetail = pDescription("StepHtmlInfo")
  m_NodeName = NodeName
  
  'Custom Reporting - output info to a log file
  sData = Date & Chr(9) & time & Chr(9) & "Node" & Chr(9) & "[NEW NODE]" & m_NodeName & ", [NODE_DETAIL]" & NodeDetail '& vbcrlf  
  m_oTextStream.WriteLine sData
  
  'Maintain the built-in capabilities
  intContext = goBuiltInReporter.LogEvent(et, pDescription, ParentId)

  LogEvent = intContext
 End Function

 'Add custom reporting capabilities to UnSetContext()
 Public Sub UnSetContext()
    Dim sData
   
  'Custom Reporting - output info to a log file
   sData = Date & Chr(9) & time & Chr(9) & "Node" & Chr(9) & "[CLOSED NODE]" & m_NodeName '& vbcrlf  
  m_oTextStream.WriteLine sData
  
  ''Maintain the built-in capabilities
  goBuiltInReporter.UnSetContext
 End Sub

 '--------------------------------------------------------------------------------
 'Maintain the built-in capabilities
 '--------------------------------------------------------------------------------
 Public Function GetContext()         
  Dim sContext
  sContext = goBuiltInReporter.GetContext  
  GetContext = sContext
 End Function

 Public Sub SetContext(EventId)
  goBuiltInReporter.SetContext EventId
 End Sub

 Public Sub GetParentId(Id)  
    Call goBuiltInReporter.GetParentId(Id)
 End Sub

 Public Sub ReStoreContext()   
    Call goBuiltInReporter.ReStoreContext()
 End Sub

 Public Sub SetRegistryRoot(Root)   
    Call goBuiltInReporter.SetRegistryRoot(Root)
 End Sub

 Public Sub SetStatus(Id, Status)   
    Call goBuiltInReporter.SetStatus(Id, Status)
 End Sub

 Public Sub StoreContext()   
    Call goBuiltInReporter.StoreContext()
 End Sub

 '--------------------------------------------------------------------------------
 'Set & Get our own custom Run Status property
 '--------------------------------------------------------------------------------
 Public Property Let CurrentRunStatus(iStatus) 
  m_CurrentRunStatus = iStatus
 End Property

 Public Property Get CurrentRunStatus() 
  CurrentRunStatus = m_CurrentRunStatus
 End Property

 '--------------------------------------------------------------------------------
 'Set & Get our own custom log file path
 '--------------------------------------------------------------------------------
 Public Property Let LogFilePath(sPath) 
  m_sLogFilePath = sPath
 End Property

 Public Property Get LogFilePath()
  LogFilePath = m_sLogFilePath
 End Property

 '---------------------
 'Constructor
 '---------------------
 Private Sub Class_Initialize
  'Set all the Built-in Reporter properties to our custom reporter object
  Filter = goBuiltInReporter.Filter
  'Set FilterEx = goBuiltInReporter.FilterEx  'Not quite working here  
  ReportPath = goBuiltInReporter.ReportPath
  RunStatus = goBuiltInReporter.RunStatus

  'Track the custom node name which is using by Reporter_AddNode()
  m_NodeName = ""

  'Init the custom run status info
  m_CurrentRunStatus = 2
  
    'Create a unique result log file name based on the Built-in Reporter object info   
    m_sLogFilePath = Get_LogFileName

    'Create a log file
  Set m_oFSO = CreateObject("Scripting.FileSystemObject")   
  Set m_oTextStream = m_oFSO.OpenTextFile(m_sLogFilePath, 8, True) '8=append
 End Sub

 'Create a log file based on the script path
 Function Get_LogFileName()  
  Get_LogFileName = goBuiltInReporter.ReportPath & "\log.txt"
 End Function

 '---------------------
 'Destructor
 '---------------------
 Private Sub Class_Terminate()  
  Set  m_oFSO = Nothing
  Set  m_oTextStream = Nothing
 End Sub
 
End Class

CustomReporter.zip