Beispiel #1
0
        /// <summary>
        /// Reads a JUnit results file from disk, converts it into a TestRunData object.
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="runContext"></param>
        /// <returns></returns>
        public TestRunData ReadResults(IExecutionContext executionContext, string filePath, TestRunContext runContext = null)
        {
            // http://windyroad.com.au/dl/Open%20Source/JUnit.xsd

            XmlDocument doc = new XmlDocument();

            try
            {
                var settings = new XmlReaderSettings
                {
                    DtdProcessing = DtdProcessing.Ignore
                };

                using (XmlReader reader = XmlReader.Create(filePath, settings))
                {
                    doc.Load(reader);
                }
            }
            catch (XmlException ex)
            {
                executionContext.Warning(StringUtil.Loc("FailedToReadFile", filePath, ex.Message));
                return(null);
            }

            //init test run summary information - run name, host name, start time
            TestSuiteSummary runSummary = new TestSuiteSummary(Name);

            IdentityRef runUserIdRef = null;
            string      runUser      = runContext != null ? runContext.Owner : string.Empty;

            if (!string.IsNullOrEmpty(runUser))
            {
                runUserIdRef = new IdentityRef()
                {
                    DisplayName = runUser
                };
            }

            var presentTime = DateTime.UtcNow;

            runSummary.TimeStamp = DateTime.MaxValue;
            var maxCompletedTime = DateTime.MinValue;

            //read data from testsuite nodes

            XmlNode testSuitesNode = doc.SelectSingleNode("testsuites");

            if (testSuitesNode != null)
            {
                //found testsuites node - some plugins generate it like karma junit plugin
                XmlNodeList testSuiteNodeList = doc.SelectNodes("/testsuites/testsuite");
                if (testSuiteNodeList != null)
                {
                    foreach (XmlNode testSuiteNode in testSuiteNodeList)
                    {
                        //for each available suites get all suite details
                        TestSuiteSummary testSuiteSummary = ReadTestSuite(testSuiteNode, runUserIdRef);

                        // sum up testsuite durations and test case durations, decision on what to use will be taken later
                        runSummary.TotalTestCaseDuration   = runSummary.TotalTestCaseDuration.Add(testSuiteSummary.TotalTestCaseDuration);
                        runSummary.TestSuiteDuration       = runSummary.TestSuiteDuration.Add(testSuiteSummary.TestSuiteDuration);
                        runSummary.SuiteTimeDataAvailable  = runSummary.SuiteTimeDataAvailable && testSuiteSummary.SuiteTimeDataAvailable;
                        runSummary.SuiteTimeStampAvailable = runSummary.SuiteTimeStampAvailable && testSuiteSummary.SuiteTimeStampAvailable;
                        runSummary.Host = testSuiteSummary.Host;
                        runSummary.Name = testSuiteSummary.Name;
                        //stop calculating timestamp information, if timestamp data is not avilable for even one test suite
                        if (testSuiteSummary.SuiteTimeStampAvailable)
                        {
                            runSummary.TimeStamp = runSummary.TimeStamp > testSuiteSummary.TimeStamp ? testSuiteSummary.TimeStamp : runSummary.TimeStamp;
                            DateTime completedTime = testSuiteSummary.TimeStamp.AddTicks(testSuiteSummary.TestSuiteDuration.Ticks);
                            maxCompletedTime = maxCompletedTime < completedTime ? completedTime : maxCompletedTime;
                        }
                        runSummary.Results.AddRange(testSuiteSummary.Results);
                    }

                    if (testSuiteNodeList.Count > 1)
                    {
                        runSummary.Name = Name + "_" + Path.GetFileName(filePath);
                    }
                }
            }
            else
            {
                XmlNode testSuiteNode = doc.SelectSingleNode("testsuite");
                if (testSuiteNode != null)
                {
                    runSummary = ReadTestSuite(testSuiteNode, runUserIdRef);
                    //only if start time is available then only we need to calculate completed time
                    if (runSummary.TimeStamp != DateTime.MaxValue)
                    {
                        DateTime completedTime = runSummary.TimeStamp.AddTicks(runSummary.TestSuiteDuration.Ticks);
                        maxCompletedTime = maxCompletedTime < completedTime ? completedTime : maxCompletedTime;
                    }
                    else
                    {
                        runSummary.SuiteTimeStampAvailable = false;
                    }
                }
            }

            if (runContext != null && !string.IsNullOrWhiteSpace(runContext.RunName))
            {
                runSummary.Name = runContext.RunName;
            }

            if (!runSummary.SuiteTimeStampAvailable)
            {
                executionContext.Output("Timestamp is not available for one or more testsuites. Total run duration is being calculated as the sum of time durations of detected testsuites");

                if (!runSummary.SuiteTimeDataAvailable)
                {
                    executionContext.Output("Time is not available for one or more testsuites. Total run duration is being calculated as the sum of time durations of detected testcases");
                }
            }
            //if start time is not calculated then it should be initialized as present time
            runSummary.TimeStamp = runSummary.TimeStamp == DateTime.MaxValue
                ? presentTime
                : runSummary.TimeStamp;
            //if suite timestamp data is not available even for single testsuite, then fallback to testsuite run time
            //if testsuite run time is not available even for single testsuite, then fallback to total test case duration
            maxCompletedTime = !runSummary.SuiteTimeStampAvailable || maxCompletedTime == DateTime.MinValue
                ? runSummary.TimeStamp.Add(runSummary.SuiteTimeDataAvailable ? runSummary.TestSuiteDuration
                : runSummary.TotalTestCaseDuration) : maxCompletedTime;
            //create test run data
            var testRunData = new TestRunData(
                name: runSummary.Name,
                startedDate: runSummary.TimeStamp != DateTime.MinValue ? runSummary.TimeStamp.ToString("o") : null,
                completedDate: maxCompletedTime != DateTime.MinValue ? maxCompletedTime.ToString("o") : null,
                state: TestRunState.InProgress.ToString(),
                isAutomated: true,
                buildId: runContext != null ? runContext.BuildId : 0,
                buildFlavor: runContext != null ? runContext.Configuration : string.Empty,
                buildPlatform: runContext != null ? runContext.Platform : string.Empty,
                releaseUri: runContext != null ? runContext.ReleaseUri : null,
                releaseEnvironmentUri: runContext != null ? runContext.ReleaseEnvironmentUri : null
                )
            {
                Results     = runSummary.Results.ToArray(),
                Attachments = AddResultsFileToRunLevelAttachments ? new string[] { filePath } : new string[0]
            };

            return(testRunData);
        }
Beispiel #2
0
        /// <summary>
        /// Read testcases under testsuite node in xml
        /// </summary>
        /// <param name="rootNode"></param>
        private TestSuiteSummary ReadTestSuite(XmlNode rootNode, IdentityRef runUserIdRef)
        {
            TestSuiteSummary testSuiteSummary       = new TestSuiteSummary(Name);
            TimeSpan         totalTestSuiteDuration = TimeSpan.Zero;
            TimeSpan         totalTestCaseDuration  = TimeSpan.Zero;

            if (rootNode.Attributes["name"] != null && rootNode.Attributes["name"].Value != null)
            {
                testSuiteSummary.Name = rootNode.Attributes["name"].Value;
            }

            if (rootNode.Attributes["hostname"] != null && rootNode.Attributes["hostname"].Value != null)
            {
                testSuiteSummary.Host = rootNode.Attributes["hostname"].Value;
            }

            //assume runtimes from xml are current local time since timezone information is not in the xml, if xml datetime > current local time, fallback to local start time
            DateTime     timestampFromXml = DateTime.MinValue;
            XmlAttribute timestampNode    = rootNode.Attributes["timestamp"];

            if (timestampNode != null && timestampNode.Value != null)
            {
                if (DateTime.TryParse(timestampNode.Value, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out timestampFromXml))
                {
                    testSuiteSummary.TimeStamp = timestampFromXml;
                }
            }

            if (timestampFromXml == DateTime.MinValue)
            {
                testSuiteSummary.SuiteTimeStampAvailable = false;
            }

            bool SuiteTimeDataAvailable = false;

            totalTestSuiteDuration = GetTimeSpan(rootNode, out SuiteTimeDataAvailable);
            testSuiteSummary.SuiteTimeDataAvailable = SuiteTimeDataAvailable;

            var testSuiteStartTime = testSuiteSummary.TimeStamp;

            //find test case nodes in JUnit result xml
            XmlNodeList testCaseNodes = rootNode.SelectNodes("./testcase");

            if (testCaseNodes != null)
            {
                DateTime testCaseStartTime = testSuiteStartTime;

                //Add test case results to the test run
                foreach (XmlNode testCaseNode in testCaseNodes)
                {
                    TestCaseResultData resultCreateModel = new TestCaseResultData();

                    //test case name and type
                    if (testCaseNode.Attributes["name"] != null && testCaseNode.Attributes["name"].Value != null)
                    {
                        resultCreateModel.TestCaseTitle     = testCaseNode.Attributes["name"].Value;
                        resultCreateModel.AutomatedTestName = testCaseNode.Attributes["name"].Value;
                    }

                    if (testCaseNode.Attributes["classname"] != null && testCaseNode.Attributes["classname"].Value != null)
                    {
                        resultCreateModel.AutomatedTestStorage = testCaseNode.Attributes["classname"].Value;
                    }

                    if (testCaseNode.Attributes["owner"]?.Value != null)
                    {
                        var ownerName = testCaseNode.Attributes["owner"].Value;
                        resultCreateModel.Owner = new IdentityRef {
                            DisplayName = ownerName, DirectoryAlias = ownerName
                        };
                    }

                    //test case duration
                    bool TestCaseTimeDataAvailable = false;
                    var  testCaseDuration          = GetTimeSpan(testCaseNode, out TestCaseTimeDataAvailable);
                    totalTestCaseDuration           = totalTestCaseDuration + testCaseDuration;
                    resultCreateModel.DurationInMs  = testCaseDuration.TotalMilliseconds;
                    resultCreateModel.StartedDate   = testCaseStartTime;
                    resultCreateModel.CompletedDate = testCaseStartTime.AddTicks(testCaseDuration.Ticks);
                    testCaseStartTime = testCaseStartTime.AddTicks(1) + testCaseDuration; //next start time

                    //test case outcome
                    XmlNode failure, error, skipped;

                    if ((failure = testCaseNode.SelectSingleNode("./failure")) != null)
                    {
                        ProcessFailureNode(failure, resultCreateModel);
                        AddSystemLogsToResult(testCaseNode, resultCreateModel);
                    }
                    else if ((error = testCaseNode.SelectSingleNode("./error")) != null)
                    {
                        ProcessFailureNode(error, resultCreateModel);
                        AddSystemLogsToResult(testCaseNode, resultCreateModel);
                    }
                    else if ((skipped = testCaseNode.SelectSingleNode("./skipped")) != null)
                    {
                        resultCreateModel.Outcome = TestOutcome.NotExecuted.ToString();
                        if (skipped.Attributes["message"] != null && !string.IsNullOrWhiteSpace(skipped.Attributes["message"].Value))
                        {
                            resultCreateModel.ErrorMessage = skipped.Attributes["message"].Value;
                        }
                    }
                    else
                    {
                        resultCreateModel.Outcome = TestOutcome.Passed.ToString();
                    }

                    resultCreateModel.State = "Completed";

                    resultCreateModel.AutomatedTestType = Name;

                    //other properties - host name and user
                    resultCreateModel.ComputerName = testSuiteSummary.Host;

                    if (runUserIdRef != null)
                    {
                        resultCreateModel.RunBy = runUserIdRef;
                    }

                    if (!string.IsNullOrEmpty(resultCreateModel.AutomatedTestName) && !string.IsNullOrEmpty(resultCreateModel.TestCaseTitle))
                    {
                        testSuiteSummary.Results.Add(resultCreateModel);
                    }
                }
            }

            testSuiteSummary.TestSuiteDuration     = totalTestSuiteDuration;
            testSuiteSummary.TotalTestCaseDuration = totalTestCaseDuration;

            return(testSuiteSummary);
        }
        /// <summary>
        /// Reads a JUnit results file from disk, converts it into a TestRunData object.        
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="runContext"></param>
        /// <returns></returns>
        public TestRunData ReadResults(IExecutionContext executionContext, string filePath, TestRunContext runContext = null)
        {
            // http://windyroad.com.au/dl/Open%20Source/JUnit.xsd

            XmlDocument doc = new XmlDocument();
            try
            {
                var settings = new XmlReaderSettings
                {
                    DtdProcessing = DtdProcessing.Prohibit
                };

                using (XmlReader reader = XmlReader.Create(filePath, settings))
                {
                    doc.Load(reader);
                }
            }
            catch (XmlException ex)
            {
                executionContext.Warning(StringUtil.Loc("FailedToReadFile", filePath, ex.Message));
                return null;
            }

            //init test run summary information - run name, host name, start time
            TestSuiteSummary runSummary = new TestSuiteSummary(Name);

            IdentityRef runUserIdRef = null;
            string runUser = runContext != null ? runContext.Owner : string.Empty;
            if (!string.IsNullOrEmpty(runUser))
            {
                runUserIdRef = new IdentityRef() { DisplayName = runUser };
            }

            //read data from testsuite nodes

            XmlNode testSuitesNode = doc.SelectSingleNode("testsuites");
            if (testSuitesNode != null)
            {
                //found testsuites node - some plugins generate it like karma junit plugin
                XmlNodeList testSuiteNodeList = doc.SelectNodes("/testsuites/testsuite");
                if (testSuiteNodeList != null)
                {
                    foreach (XmlNode testSuiteNode in testSuiteNodeList)
                    {
                        TestSuiteSummary testSuiteSummary = ReadTestSuite(testSuiteNode, runUserIdRef);
                        runSummary.Duration = runSummary.Duration.Add(testSuiteSummary.Duration);
                        runSummary.Results.AddRange(testSuiteSummary.Results);
                        runSummary.Host = testSuiteSummary.Host;
                        runSummary.Name = testSuiteSummary.Name;
                    }

                    if (testSuiteNodeList.Count > 1)
                    {
                        runSummary.Name = Name + "_" + Path.GetFileName(filePath);
                    }
                }
            }
            else
            {
                XmlNode testSuiteNode = doc.SelectSingleNode("testsuite");
                if (testSuiteNode != null)
                {
                    runSummary = ReadTestSuite(testSuiteNode, runUserIdRef);
                }
            }

            if (runContext != null && !string.IsNullOrWhiteSpace(runContext.RunName))
            {
                runSummary.Name = runContext.RunName;
            }

            if (runSummary.Results.Count > 0)
            {
                //first testsuite starteddate is the starteddate of the run
                runSummary.TimeStamp = DateTime.Parse(runSummary.Results[0].StartedDate);
            }

            //create test run data
            var testRunData = new TestRunData(
                name: runSummary.Name,
                startedDate: runSummary.TimeStamp.ToString("o"),
                completedDate: runSummary.TimeStamp.Add(runSummary.Duration).ToString("o"),
                state: TestRunState.InProgress.ToString(),
                isAutomated: true,
                buildId: runContext != null ? runContext.BuildId : 0,
                buildFlavor: runContext != null ? runContext.Configuration : string.Empty,
                buildPlatform: runContext != null ? runContext.Platform : string.Empty,
                releaseUri: runContext != null ? runContext.ReleaseUri : null,
                releaseEnvironmentUri: runContext != null ? runContext.ReleaseEnvironmentUri : null
                )
            {
                Results = runSummary.Results.ToArray(),
                Attachments = AddResultsFileToRunLevelAttachments ? new string[] { filePath } : new string[0]

            };

            return testRunData;
        }
Beispiel #4
0
        /// <summary>
        /// Reads a JUnit results file from disk, converts it into a TestRunData object.
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="runContext"></param>
        /// <returns></returns>
        public TestRunData ReadResults(IExecutionContext executionContext, string filePath, TestRunContext runContext = null)
        {
            // http://windyroad.com.au/dl/Open%20Source/JUnit.xsd

            XmlDocument doc = new XmlDocument();

            try
            {
                var settings = new XmlReaderSettings
                {
                    DtdProcessing = DtdProcessing.Ignore
                };

                using (XmlReader reader = XmlReader.Create(filePath, settings))
                {
                    doc.Load(reader);
                }
            }
            catch (XmlException ex)
            {
                executionContext.Warning(StringUtil.Loc("FailedToReadFile", filePath, ex.Message));
                return(null);
            }

            //init test run summary information - run name, host name, start time
            TestSuiteSummary runSummary = new TestSuiteSummary(Name);

            IdentityRef runUserIdRef = null;
            string      runUser      = runContext != null ? runContext.Owner : string.Empty;

            if (!string.IsNullOrEmpty(runUser))
            {
                runUserIdRef = new IdentityRef()
                {
                    DisplayName = runUser
                };
            }

            //read data from testsuite nodes

            XmlNode testSuitesNode = doc.SelectSingleNode("testsuites");

            if (testSuitesNode != null)
            {
                //found testsuites node - some plugins generate it like karma junit plugin
                XmlNodeList testSuiteNodeList = doc.SelectNodes("/testsuites/testsuite");
                if (testSuiteNodeList != null)
                {
                    foreach (XmlNode testSuiteNode in testSuiteNodeList)
                    {
                        TestSuiteSummary testSuiteSummary = ReadTestSuite(testSuiteNode, runUserIdRef);
                        runSummary.Duration = runSummary.Duration.Add(testSuiteSummary.Duration);
                        runSummary.Results.AddRange(testSuiteSummary.Results);
                        runSummary.Host = testSuiteSummary.Host;
                        runSummary.Name = testSuiteSummary.Name;
                    }

                    if (testSuiteNodeList.Count > 1)
                    {
                        runSummary.Name = Name + "_" + Path.GetFileName(filePath);
                    }
                }
            }
            else
            {
                XmlNode testSuiteNode = doc.SelectSingleNode("testsuite");
                if (testSuiteNode != null)
                {
                    runSummary = ReadTestSuite(testSuiteNode, runUserIdRef);
                }
            }

            if (runContext != null && !string.IsNullOrWhiteSpace(runContext.RunName))
            {
                runSummary.Name = runContext.RunName;
            }

            if (runSummary.Results.Count > 0)
            {
                //first testsuite starteddate is the starteddate of the run
                runSummary.TimeStamp = runSummary.Results[0].StartedDate;
            }

            //create test run data
            var testRunData = new TestRunData(
                name: runSummary.Name,
                startedDate: runSummary.TimeStamp.ToString("o"),
                completedDate: runSummary.TimeStamp.Add(runSummary.Duration).ToString("o"),
                state: TestRunState.InProgress.ToString(),
                isAutomated: true,
                buildId: runContext != null ? runContext.BuildId : 0,
                buildFlavor: runContext != null ? runContext.Configuration : string.Empty,
                buildPlatform: runContext != null ? runContext.Platform : string.Empty,
                releaseUri: runContext != null ? runContext.ReleaseUri : null,
                releaseEnvironmentUri: runContext != null ? runContext.ReleaseEnvironmentUri : null
                )
            {
                Results     = runSummary.Results.ToArray(),
                Attachments = AddResultsFileToRunLevelAttachments ? new string[] { filePath } : new string[0]
            };

            return(testRunData);
        }
        /// <summary>
        /// Read testcases under testsuite node in xml
        /// </summary>
        /// <param name="rootNode"></param>
        private TestSuiteSummary ReadTestSuite(XmlNode rootNode, IdentityRef runUserIdRef)
        {
            TestSuiteSummary testSuiteSummary = new TestSuiteSummary(Name);
            TimeSpan totalTestSuiteDuration = TimeSpan.Zero;
            TimeSpan totalTestCaseDuration = TimeSpan.Zero;

            if (rootNode.Attributes["name"] != null && rootNode.Attributes["name"].Value != null)
            {
                testSuiteSummary.Name = rootNode.Attributes["name"].Value;
            }

            if (rootNode.Attributes["hostname"] != null && rootNode.Attributes["hostname"].Value != null)
            {
                testSuiteSummary.Host = rootNode.Attributes["hostname"].Value;
            }

            //assume runtimes from xml are current local time since timezone information is not in the xml, if xml datetime > current local time, fallback to local start time
            DateTime timestampFromXml = DateTime.MinValue;
            XmlAttribute timestampNode = rootNode.Attributes["timestamp"];
            if (timestampNode != null && timestampNode.Value != null)
            {
                if (DateTime.TryParse(timestampNode.Value, out timestampFromXml))
                {
                    testSuiteSummary.TimeStamp = timestampFromXml;
                }
            }

            totalTestSuiteDuration = GetTimeSpan(rootNode);

            DateTime testSuiteStartTime = testSuiteSummary.TimeStamp;

            //find test case nodes in JUnit result xml
            XmlNodeList testCaseNodes = rootNode.SelectNodes("./testcase");
            if (testCaseNodes != null)
            {
                DateTime testCaseStartTime = testSuiteStartTime;

                //Add test case results to the test run
                foreach (XmlNode testCaseNode in testCaseNodes)
                {
                    TestCaseResultData resultCreateModel = new TestCaseResultData();

                    //test case name and type
                    if (testCaseNode.Attributes["name"] != null && testCaseNode.Attributes["name"].Value != null)
                    {
                        resultCreateModel.TestCaseTitle = testCaseNode.Attributes["name"].Value;
                        resultCreateModel.AutomatedTestName = testCaseNode.Attributes["name"].Value;
                    }

                    if (testCaseNode.Attributes["classname"] != null && testCaseNode.Attributes["classname"].Value != null)
                    {
                        resultCreateModel.AutomatedTestStorage = testCaseNode.Attributes["classname"].Value;
                    }

                    //test case duration
                    TimeSpan testCaseDuration = GetTimeSpan(testCaseNode);
                    resultCreateModel.DurationInMs = testCaseDuration.TotalMilliseconds.ToString(CultureInfo.InvariantCulture);

                    resultCreateModel.StartedDate = testCaseStartTime.ToString("o");
                    resultCreateModel.CompletedDate = testCaseStartTime.AddTicks(testCaseDuration.Ticks).ToString("o");
                    testCaseStartTime = testCaseStartTime.AddTicks(1) + testCaseDuration; //next start time

                    //test case outcome
                    XmlNode failure, error, skipped;

                    if ((failure = testCaseNode.SelectSingleNode("./failure")) != null)
                    {
                        ProcessFailureNode(failure, resultCreateModel);
                    }
                    else if ((error = testCaseNode.SelectSingleNode("./error")) != null)
                    {
                        ProcessFailureNode(error, resultCreateModel);
                    }
                    else if ((skipped = testCaseNode.SelectSingleNode("./skipped")) != null)
                    {
                        resultCreateModel.Outcome = TestOutcome.NotExecuted.ToString();
                        if (skipped.Attributes["message"] != null && !string.IsNullOrWhiteSpace(skipped.Attributes["message"].Value))
                        {
                            resultCreateModel.ErrorMessage = skipped.Attributes["message"].Value;
                        }
                    }
                    else
                    {
                        resultCreateModel.Outcome = TestOutcome.Passed.ToString();
                    }

                    resultCreateModel.State = "Completed";

                    resultCreateModel.AutomatedTestType = Name;

                    //other properties - host name and user
                    resultCreateModel.ComputerName = testSuiteSummary.Host;

                    if (runUserIdRef != null)
                    {
                        resultCreateModel.RunBy = runUserIdRef;
                        resultCreateModel.Owner = runUserIdRef;
                    }

                    if (!string.IsNullOrEmpty(resultCreateModel.AutomatedTestName) && !string.IsNullOrEmpty(resultCreateModel.TestCaseTitle))
                    {
                        testSuiteSummary.Results.Add(resultCreateModel);
                    }

                }
            }

            if (TimeSpan.Compare(totalTestSuiteDuration, totalTestCaseDuration) < 0)
            {
                totalTestSuiteDuration = totalTestCaseDuration; //run duration may not be set in the xml, so use total test case duration 
            }
            testSuiteSummary.Duration = totalTestSuiteDuration;

            return testSuiteSummary;
        }