Forum Discussion

Mia's avatar
Mia
Contributor
11 years ago

Send test result via e-mail in subject

Hello,



I need to run my test project in TestComplete10 every night, and I need to be able to send result (Succeded/Error(s) occurred) as a part of a email subject.



I run the test project through command line (or I should say batch files) and I also use command line to send emails. First I thought that I always send the .mht file as an attachment, but it is to large even after compression, so I cannot use this solution. I read some other threads about this and everybody solves this using TestCompletes SendMail method. So I just wonder if there is some way to get the result from commandline.



Thanks!

Miriam
  • Hello Miriam,



    we had a similar requirement and here's how we tackled this:



    1. Create a global variable (e.g. "strTestResult")  that would hold the global test result. This is what will appear in your eMail subject later

    2. Override GeneralEvent_OnStopTest and  add sth. like this




    /*

    Function: GeneralEvents_OnStopTest()

    This method assigns global test result (FAILED, WARNING, OK) to test project according to single test results.

     

    Bubbles up to higher severity level, i.e. if WARNING is recorded in any of test cases and no FAILED recorded anywhere,

    global test outcome is WARNING. If FAILED is recorded in any test case, global result will be FAILED.

    */

    function GeneralEvents_OnStopTest(Sender)

    {

      if (Log.ErrCount > 0)

        strTestResult = "FAILED";

      else if (Log.WrnCount > 0 && Log.ErrCount == 0)

        strTestResult = strTestResult != "FAILED" ? "WARNING" : "FAILED";

      else

        strTestResult = strTestResult != "FAILED" ?

                          (strTestResult != "WARNING" ? "OK" : "WARNING") : "FAILED";

    }








    3. Export the test results from TestComplete to a temprary file after the run and then parse it for desired attributes.

    We have following method to do this, the output will be a small HTML table with a quick summary





    function GetTestSummary()

    {

      var tempFolder = "C:\\temp\\" + GetTickCount() + "\\";

     

      if (0 != aqFileSystem.CreateFolder(tempFolder))

      {

        Log.Error("The " + tempFolder + " temp folder was not created");

        return "";

      }

     

      Log.SaveResultsAs(tempFolder, lsXML);

     

      var xDoc = Sys.OleObject("MSXML2.DOMDocument.4.0");

      xDoc.load(tempFolder + "Description.tcLog");      

      // Warning count  

      var wrnC = VarToInteger(xDoc.selectSingleNode('Nodes/Node[@name="root"]/Prp[@name="warning count"]/@value').text);      

      //Error count  

      var errC = VarToInteger(xDoc.selectSingleNode('Nodes/Node[@name="root"]/Prp[@name="error count"]/@value').text);      

      //Execution time  

      var startTime = parseFloat(xDoc.selectSingleNode('Nodes/Node[@name="root"]/Prp[@name="start time"]/@value').text);  

      var stopTime = parseFloat(xDoc.selectSingleNode('Nodes/Node[@name="root"]/Prp[@name="stop time"]/@value').text);      

     

      aqFileSystem.DeleteFolder(tempFolder, true);  

     

      var cellStyle = "style=\"padding-left:5px; padding-right:5px";

      var errCntCellBg = "; background-color:" + (errC > 0 ?  "#FF704D\"" : "#ACD630\"");

      var wrnCntCellBg = "; background-color:" + (wrnC > 0 ?  "#FFFF75\"" : "#ACD630\"");

     

      var res = "<table border =\"1\">" +

                "<tr><td " + cellStyle + "\">Errors: </td><td " + cellStyle + errCntCellBg + "\">" + errC + "</td></tr>" +     

                "<tr><td " + cellStyle + "\">Warnings: </td><td " + cellStyle +  wrnCntCellBg + "\">" + wrnC + "</td></tr>" +    

                "<tr><td " + cellStyle + "\">Start Time: </td><td " + cellStyle + "\">" + aqConvert.DateTimeToStr(startTime) + "</td></tr>" +    

                "<tr><td " + cellStyle + "\">Stop Time: </td><td " + cellStyle + "\">" + aqConvert.DateTimeToStr(stopTime) + "</td></tr>" +    

                "<tr><td " + cellStyle + "\">Run Time: </td><td " + cellStyle + "\">" + aqConvert.DateTimeToFormatStr(stopTime - startTime, "%H:%M:%S") + "</td></tr>" +

                "</table>";

                  

     

      return res;   

     

    }







    4. Then call the method above and save the HTML output to a variable (see "strTestSummary"). Also save the .mht file to a directory of your choice on the server and store the path in the variable -> this will be the link to the file in the automatic eMail sent later (see below):





    function SaveAndEmailTestResults()

    {

      var FileName, NowValue, strNowValue, strTestSummary;

     

      strTestSummary = GetTestSummary();

     

     

      // Obtain the current date and time

      NowValue=aqDateTime.Now();

     

      // Convert the returned date/time value to string value

      strNowValue = aqConvert.DateTimeToFormatStr(NowValue, "%Y%m%d%H%M%S");

     

      FileName = strLogFilePath + "\\" + strNowValue + ".mht";

      Log.SaveResultsAs(FileName, 2);

     

         

       //Send eMail

       SendCDOEmail(strTestResult, strTestSummary, strAppVersionInfo, FileName);

      

       //re-initialize global test result flag

       strTestResult="";

     

    }











    5. Invoke automatic sending of eMail (see "SendCDOEmail" call above). Make sure to supply the correct input parameters (SMTP credentials etc.) :







    function SendCDOEmail(testResult,resultSummary, versionInfo, file)

    {

      var i, schema, mConfig, mMessage, mSubject, mBody;

     

      var strTestServerIP = "\\\\10.20.30.40";

     

      var strFileLink = aqString.Replace(file,"C:",strTestServerIP);

     

      mBody="Application " + versionInfo + "<br><br>" + resultSummary + "<br>Log file: <a href =\"" + strFileLink + "\">" + strFileLink + "</a>";

      mSubject= "Automated test notification: " + testResult;

      try

      {

        schema = "http://schemas.microsoft.com/cdo/configuration/";

        mConfig = Sys.OleObject("CDO.Configuration");

        mConfig.Fields.Item(schema + "sendusing") = 2; // cdoSendUsingPort

        mConfig.Fields.Item(schema + "smtpserver") = strLogSMTPServer; // SMTP server

        mConfig.Fields.Item(schema + "smtpserverport") = 25; // Port number

        mConfig.Fields.Item(schema + "MailboxURL")= strLogMailBoxUrl;

        //mConfig.Fields.Item(schema + "sendusername") = "user"; // User name (if needed)

        //mConfig.Fields.Item(schema + "sendpassword") = "pwd"; // User password (if needed)

        mConfig.Fields.Update();

     

        mMessage = Sys.OleObject("CDO.Message");

        mMessage.MimeFormatted = true;

        mMessage.Configuration = mConfig;

        mMessage.From = strLogSenderName;

        mMessage.To = strLogRecipientAddress;

        mMessage.Subject = mSubject;

        mMessage.HTMLBody = mBody;

       

       

        mMessage.Send();

       

      }

      catch (exception)

      {

        Log.Error("E-mail cannot be sent", exception.description);

        return false;

      }

      Log.Message("Message to <" + strLogRecipientAddress + "> was successfully sent");

     

     

      return true;

    }





     

    Hope this helps to point you to the right direction.



    Marin


  • Mia's avatar
    Mia
    Contributor
    Hi Marin,





    this is exactly what I want. It looks really good and it would be really really great if it worked on my project. Unfortunately I was not able to apply this on my test project. It is the GetTestSummary() function which keeps on failing. First because of the: var xDoc = Sys.OleObject("MSXML2.DOMDocument.4.0"); ... for error: Invalid class string: cannot obtain ClassID.

    I googled a little and tried to change the version in the argument to 6.0. Then it started to fail on another row: var wrnC = VarToInteger(xDoc.selectSingleNode('Nodes/Node[@name="root"]/Prp[@name="warning count"]/@value').text); ... with message: Object required.

    Until that row it seems that everything is working, the Description.tcLog is generated. So now I really don't know what's wrong because I have no experience with parsing text.



    Thanks for your help



    Miriam
  • marin's avatar
    marin
    Frequent Contributor
    Hello Miriam,



    mere changing of version in the code would not be of much help if MSXML is not installed.

    Have you made sure that MSXML 4.0 is installed on your machine?

    Have a look into your software (Start -> appwiz.cpl)...



    If it is not there in the list of installed programs, here's where you can download it:



    http://www.microsoft.com/en-US/download/details.aspx?id=15697



    Marin
  • Mia's avatar
    Mia
    Contributor
    Oh, you were right, the parser wasn't installed at all. So now it works fine, it sends emails witht the pretty table and so on. I have just last question, I hope.

    It sends the email after each tests. I have a project suite which includes about 8 test items and the count will grow. Is there any chance how to invoke this action only when whole test project ends?
  • Mia's avatar
    Mia
    Contributor
    Hi Alex,

    yes, that helped... thank you very much! :)



    And thank you all guys for help, I owe you a chocolate! :)



    Miriam
  • marin's avatar
    marin
    Frequent Contributor
    Hello Miriam,



    glad it worked for you.

    As Alex pointed out, you do not need to call the methods from every test item.

    We did it by defining a dedicated test item at the end of the project (screenshot attached).



    Regards,



    Marin
  • Mia's avatar
    Mia
    Contributor
    Hi Marin,



    yes, I did it the same way, when I found out that it works like that. I just wasn't sure that it could work, because when it's part of a tests it seems that the result is created after this routine is finished. But apparently, the result is created continuously. 



    So thank you very much again :)



    Miriam