Ask a Question

More Access To Project Test Items Info

More Access To Project Test Items Info

It would be great to have an event listener for OnProjectEnd, and / or the number of enabled test items.

 

The scenario that makes not having this a huge PIA is if you want to send an email summary at the end of  an entire Project Run with several test items.

 

The work around needed to do this required using the OnTestStop event to increment my own counter for the number of tests ran, export the logs and build the body of the email from that.

 

To email only at the end of the Project Run, I had to make sure that my number of tests ran counter was equal to the number of enabled test items. 

 

To ge tthe number of enabled test items requires looping through all test items using recursion at the start of the test. 

2 Comments
AlexKaras
Community Hero

Hi,

 

While I agree with your request, check if the following functions can be of any help.

 

'-----------------------------------------------------------------------------

' From: http://www.automatedqa.com/forums/forum/post/?mode=singleThread&thread=c5788c98-32ee-4d52-b6c7-ea734...
' Code that counts errors and warnings
' Note that if you run a project, you need to get the summary of errors and
' warnings using the GetSum function in a routine (in this case, it is PostSum)
' set as the last test item of the project. If you run a project suite,
' you need to add a project to the end of the test item list of the project suite.
' This project should contain the only test item calling the routine that uses the GetSum function.
Function LogGetErrorsSum(logFolder) ' : OleVariant;
Const cProcName = "LogGetErrorsSum"
Dim cProcNameMsgPrefix : cProcNameMsgPrefix = cUnitNameMsgPrefix & cProcName & "(): "

Dim itemsInfo : itemsInfo = BuiltIn.CreateVariantArray(0, 1) ' errorsCount, warningsCount
Dim tempFolder, xDoc
Dim wrnC, errC

itemsInfo(0) = -1
itemsInfo(1) = -1

tempFolder = logFolder

Set xDoc = Sys.OleObject("MSXML2.DOMDocument")
xDoc.load(tempFolder & "Description.tcLog")

' Warning count
wrnC = VarToInteger(xDoc.selectSingleNode( _
"Nodes/Node[@name='root']/Prp[@name='warning count']/@value").text)
itemsInfo(1) = wrnC

' Error count
errC = VarToInteger(xDoc.selectSingleNode( _
"Nodes/Node[@name='root']/Prp[@name='error count']/@value").text)
itemsInfo(0) = errC

LogGetErrorsSum = itemsInfo
End Function
'-----------------------------------------------------------------------------

Function LogGetSummaryInfo(logFolder) ' : OleVariant;
Const cProcName = "LogGetSummaryInfo"
Dim cProcNameMsgPrefix : cProcNameMsgPrefix = cUnitNameMsgPrefix & cProcName & "(): "

Dim itemsInfo : itemsInfo = BuiltIn.CreateVariantArray(0, 3) ' total, executed, passed, failed
Dim tempFolder, xDoc, rootItem, summaryNode

itemsInfo(0) = -1
itemsInfo(1) = -1
itemsInfo(2) = -1
itemsInfo(3) = -1

tempFolder = aqFileSystem.IncludeTrailingBackSlash(logFolder)

Set xDoc = Sys.OleObject("MSXML2.DOMDocument")
xDoc.load(tempFolder & "RootLogData.dat")

' find the name of the file with the root log node
rootItem = xDoc.selectSingleNode("Nodes/Node/Node[@name='item 0']/Prp[@name='filename']/@value").text

xDoc.load(tempFolder & rootItem)

' find the summary node
Set summaryNode = xDoc.selectSingleNode("Nodes/Node/Node[@name='summary']")
If (summaryNode.hasChildNodes) Then
' commented line fails for some reason with this error:
' Unknown method. Node[@name='total']/Prp[-->starts-with(@<--name, 'total')]/@value
' http://stackoverflow.com/questions/10801399/how-to-select-nodes-by-attribute-that-starts-with-in-c-s...
' http://support2.microsoft.com/kb/303516
' itemsInfo(0) = VarToInteger(summaryNode.selectSingleNode("Node[@name='total']/Prp[starts-with(@name, 'total')]/@value").text)
itemsInfo(0) = VarToInteger(summaryNode.selectSingleNode("Node[@name='total']/Prp[@name='total (sum)']/@value").text)
itemsInfo(1) = VarToInteger(summaryNode.selectSingleNode("Node[@name='executed']/Prp[@name='total (sum)']/@value").text)
itemsInfo(2) = VarToInteger(summaryNode.selectSingleNode("Node[@name='passed']/Prp[@name='total (sum)']/@value").text)
itemsInfo(3) = VarToInteger(summaryNode.selectSingleNode("Node[@name='failed']/Prp[@name='total (sum)']/@value").text)
End If

LogGetSummaryInfo = itemsInfo
End Function
'-----------------------------------------------------------------------------

' Function counts the number of groups and testitems (enabled/disabled) in the project
' From: http://www.automatedqa.com/forums/forum/post/?mode=singleThread&thread=609e4fae-3925-40d2-b637-20a53...
Function LogGetTestItemsInfo(testItems) ': integer;
Const cProcName = "LogGetTestItemsInfo"
Dim cProcNameMsgPrefix : cProcNameMsgPrefix = cUnitNameMsgPrefix & cProcName & "(): "

Dim itemsInfo : itemsInfo = BuiltIn.CreateVariantArray(0, 2) ' groupsCount, itemsCount, enabledItemsCount
Dim i, testItem
Dim childItemsInfo : childItemsInfo = BuiltIn.CreateVariantArray(0, 2) ' groupsCount, itemsCount, enabledItemsCount

itemsInfo(0) = 0
itemsInfo(1) = 0
itemsInfo(2) = 0

For i = 0 To testItems.ItemCount - 1
Set testItem = testItems.TestItem(i)
If (testItem.ElementToBeRun Is Nothing) Then _
itemsInfo(0) = itemsInfo(0) + 1

If (testItem.ItemCount <> 0) Then
childItemsInfo = LogGetTestItemsInfo(testItem)
itemsInfo(0) = itemsInfo(0) + childItemsInfo(0)
itemsInfo(1) = itemsInfo(1) + childItemsInfo(1)
If (testItem.Enabled) Then _
itemsInfo(2) = itemsInfo(2) + childItemsInfo(2)
Else
itemsInfo(1) = itemsInfo(1) + 1
If (testItem.Enabled) Then _
itemsInfo(2) = itemsInfo(2) + 1
End If
Next ' i
LogGetTestItemsInfo = itemsInfo
End Function
'-----------------------------------------------------------------------------

Sub LogPostSummaryInfoDynamic
Const cProcName = "SysMappingRecordsetGetValue"
Dim cProcNameMsgPrefix : cProcNameMsgPrefix = cUnitNameMsgPrefix & cProcName & "(): "

Dim itemsInfo : itemsInfo = BuiltIn.CreateVariantArray(0, 3) ' total, executed, passed, failed
Dim itemsErrorsInfo : itemsErrorsInfo = BuiltIn.CreateVariantArray(0, 1) ' errorsCount, warningsCount
Dim itemsProjectInfo : itemsProjectInfo = BuiltIn.CreateVariantArray(0, 2) ' groupsCount, itemsCount, enabledItemsCount
Dim tempFolder

tempFolder = aqString.Format("%s~TC%s\", _
aqFileSystem.IncludeTrailingBackSlash( _
aqEnvironment.GetEnvironmentVariable("temp")), _
aqConvert.DateTimeToFormatStr(aqDateTime.Now, "%Y%m%d_%H%M%S"))

Call aqFileSystem.CreateFolder(tempFolder)

Call Log.SaveResultsAs(tempFolder, lsXML)

itemsInfo = LogGetSummaryInfo(tempFolder)
itemsErrorsInfo = LogGetErrorsSum(tempFolder)
itemsProjectInfo = LogGetTestItemsInfo(Project.TestItems)

Call aqFileSystem.DeleteFolder(tempFolder, True)

Call Log.Message("Test Summary Information (see Additional Info log tab)", _
"Total number of test items been ran: " & VarToStr(itemsInfo(0)) & vbCrLf & _
"Executed project test items: " & VarToStr(itemsInfo(1)) & _
aqString.Format(" (%.2f%%)", VarToInt(itemsInfo(1)) / VarToInt(itemsInfo(0)) * 100) & vbCrLf & _
"Project test items executed successfully: " & VarToStr(itemsInfo(2)) & _
aqString.Format(" (%.2f%%)", VarToInt(itemsInfo(2)) / VarToInt(itemsInfo(1)) * 100) & vbCrLf & _
"Failed project test items: " & VarToStr(itemsInfo(3)) & _
aqString.Format(" (%.2f%%)", VarToInt(itemsInfo(3)) / VarToInt(itemsInfo(1)) * 100) & vbCrLf & _
"Errors count: " & VarToStr(itemsErrorsInfo(0)) & vbCrLf & _
"Warnings count: " & VarToStr(itemsErrorsInfo(1)) & vbCrLf & _
vbCrLf & _
"# of Test Item Groups (total): " & VarToStr(itemsProjectInfo(0)) + vbCrLf & _
"Project Test Items (total): " & VarToStr(itemsProjectInfo(1)) + vbCrLf & _
"Enabled Project Test Items (total): " & VarToStr(itemsProjectInfo(2)) & _
aqString.Format(" (%.2f%%)", VarToInt(itemsProjectInfo(2)) / VarToInt(itemsProjectInfo(1)) * 100) _
)
End Sub
'-----------------------------------------------------------------------------

cunderw
Community Hero

That's actually very simlar to what I did. It's just a pain that it has to be done this way IMO

 

Here is how I did it. Note, it's more specfic to our needs.

 

 

 

var runCount = 0;
var totalTests = getNumEnabledTests(Project.TestItems);
function GeneralEvents_OnStopTest(Sender) {
  if (Project.Variables.postRunEnabled) {
      // exports and emails log summary
      runCount++;
      try {
        BuildAndSendLogs();
      }
      catch(err) {
        Log.Warning(err);        
      }
  }
  else {
    Log.Message("PostRun Disabled");
  }
}

function BuildAndSendLogs() {
  // checks if a test passed or failed and sets status for email subject
  var testStatus = GetTestStatus();
  if (testStatus == "FAILED") {
    projectStatus = "FAILED";
  }
  
  // builds email body
  emailBody += "\n\n" + GetLogItems();    
  // if all tests have ran, send the email
  if (runCount == totalTests) {
    emailBody += "\n\nEnd Time: " + aqDateTime.Now(); 
    emailSubject += " " + projectStatus;
    try {
      if (SendMail(emailAddressTo, emailServer, emailWho, emailAddressSender, emailSubject, emailBody)) 
        Log.Message("Mail was sent");
      else 
        Log.Warning("Mail was not sent");
    }
    catch(err) {
      Log.Warning("Error building email and sending: " + err);
    }
  }
}

function GetLogItems() {
  // creates a random temp folder to export the logs too
  var tempFolder = aqEnvironment.GetEnvironmentVariable("temp") + "\\" + 
                    GetTickCount() + "\\";
  if (0 != aqFileSystem.CreateFolder(tempFolder)) {
    Log.Error("The " + tempFolder + " temp folder was not created");
    return "";
  }
  // exports the log to the created folder
  if (!Log.SaveResultsAs(tempFolder, lsHTML, false, 2)) {
    Log.Error("Log was not exported to the " + tempFolder + " temp folder");
    return "";
  }
  // loads the xml from the xpoerted log
  var xDoc = Sys.OleObject("MSXML2.DOMDocument.4.0");
  xDoc.load(tempFolder + "root.xml");
  // calls logdatatext with the needed node from the xml file                                            
  var result = LogDataToText(xDoc.childNodes.item(1), 0, "  ");
  // deletes temp folder
  aqFileSystem.DeleteFolder(tempFolder, true);
  return result;   
}
 
function LogDataToText(logData, indentIndex, indentSymbol) {
  // if this doesn't match it means something was not exported correct so it returns empty string
  if ("LogData" != logData.nodeName) {
    return "";
  }
  var result = "";
  for(var i = 0; i < indentIndex; i++) {
    result += indentSymbol;
  }
  result = result + "Name: " + logData.getAttribute("name") + indentSymbol + "Status:" + indentSymbol + 
            GetTextOfStatus(logData.getAttribute("status")) + "\r\n";
  for(var i = 0; i < logData.childNodes.length; i++) {
    result += LogDataToText(logData.childNodes.item(i), indentIndex + 1, indentSymbol);
  }
  return result;
}
 
function GetTextOfStatus(statusIndex) {
// returns text for a status code
  switch(statusIndex) {
    case "0": return "PASSED";
    case "1": return "WARNING";
    case "2": return "FAILED";
    default: return "UNDEFINED";
  }
}

function GetTestStatus() {
// returns status code
  var result;
  var tempFolder = aqEnvironment.GetEnvironmentVariable("temp") + "\\" + 
                    GetTickCount() + "\\";
  if (0 != aqFileSystem.CreateFolder(tempFolder)) {
    Log.Error("The " + tempFolder + " temp folder was not created");
    return "";
  }
  if (!Log.SaveResultsAs(tempFolder, lsHTML, false, 2)) {
    Log.Error("Log was not exported to the " + tempFolder + " temp folder");
    return "";
  }
  var xDoc = Sys.OleObject("MSXML2.DOMDocument.4.0");
  xDoc.load(tempFolder + "root.xml");
  var logData = xDoc.childNodes.item(1);
  result = GetTextOfStatus(logData.getAttribute("status"));
  aqFileSystem.DeleteFolder(tempFolder, true);
  return result;   
}


function getNumEnabledTests(testItems) {
  if(getNumEnabledTests.enabledCount == undefined) {
    getNumEnabledTests.enabledCount = 0;
  }
  var itemCount = testItems.ItemCount;
  
// buids total tests based on if they are enabled.
// note this is super hacky, but I dunno how else to get it
  for(var i = 0; i < itemCount; i++) {
    if(testItems.TestItem(i).Enabled) {
      if(testItems.TestItem(i).ElementToBeRun != null) {
        getNumEnabledTests.enabledCount++;
      }
      if(testItems.TestItem(i).ItemCount != 0) {
        getNumEnabledTests(testItems.TestItem(i));
      }
    }
  }
  return getNumEnabledTests.enabledCount;
}
Announcements
Welcome to the TestComplete Feature Requests board!

Here you can review submitted feature requests and vote up the ones you like! If you can't find the feature you want - go ahead and suggest your own idea. Ideas with the highest rating can be implemented in the product.

Check out the Create a Feature Request guide for more information.
New Here?
Welcome to the Community
Sign Up Here