예제 #1
0
        public static TestStats operator +(TestStats a, TestStats b)
        {
            var testStats = new TestStats();

            a = a ?? new TestStats();
            b = b ?? new TestStats();

            testStats.Tests        = a.Tests + b.Tests;
            testStats.Errors       = a.Errors + b.Errors;
            testStats.Failures     = a.Failures + b.Failures;
            testStats.NotRun       = a.NotRun + b.NotRun;
            testStats.Inconclusive = a.Inconclusive + b.Inconclusive;
            testStats.Ignored      = a.Ignored + b.Ignored;
            testStats.Skipped      = a.Skipped + b.Skipped;
            testStats.Invalid      = a.Invalid + b.Invalid;

            testStats.Platform.Append(a.Platform);
            foreach (var part in b.Platform.ToString().Split(','))
            {
                if (!testStats.Platform.ToString().Contains(part.Trim()))
                {
                    if (testStats.Platform.Length > 0)
                    {
                        testStats.Platform.Append(", ");
                    }
                    testStats.Platform.Append(part);
                }
            }
            return(testStats);
        }
        private static string AddStatistics(TestStats test, string statClass = "stat", string valClass = "val")
        {
            var html = new StringBuilder();

            html.AppendLine(AddStatisticsCell("Tests", test.Tests, statClass, valClass + " ignore-val", false));
            html.AppendLine(AddStatisticsCell("Failures", test.Failures, statClass, valClass, true));
            html.AppendLine(AddStatisticsCell("Errors", test.Errors, statClass, valClass, true));
            html.AppendLine(AddStatisticsCell("Not\u00A0Run", test.NotRun, statClass, valClass, true));
            html.AppendLine(AddStatisticsCell("Inconclusive", test.Inconclusive, statClass, valClass, true));
            html.AppendLine(AddStatisticsCell("Ignored", test.Ignored, statClass, valClass, true));
            html.AppendLine(AddStatisticsCell("Skipped", test.Skipped, statClass, valClass, true));
            html.AppendLine(AddStatisticsCell("Invalid", test.Invalid, statClass, valClass, true));
            if (test.Date.Ticks > 0)
            {
                html.AppendLine(AddStatisticsCell("Date", test.Date.ToString("d MMM"), statClass, valClass));
                html.AppendLine(AddStatisticsCell("Time", test.Date.ToShortTimeString(), statClass, valClass));
            }
            if (test.Platform.Length > 0)
            {
                html.AppendLine(AddStatisticsCell("Platform", test.Platform.ToString(), statClass, valClass));
            }
            html.AppendLine(AddStatisticsCell("Success", string.Format("{0}%", 100 - test.Percentage),
                                              statClass, valClass));
            return(html.ToString());
        }
        /// <summary>
        /// Process the results file.
        /// </summary>
        /// <param name="file">The filename of the XML results file to parse.</param>
        /// <param name = "verbose"><c>true</c> to display status message, otherwise <c>false</c></param>
        /// <returns>
        /// HTML page content.
        /// </returns>
        private static string ProcessFile(string file, bool verbose)
        {
            if (verbose)
            {
                Console.WriteLine("Processing {0}", file);
            }
            var      html = new StringBuilder();
            XElement doc  = XElement.Load(file);

            _fileCount++;

            // Load summary values
            var test = TestStats.Parse(doc);

            TotalTest += test;

            // Summary panel
            html.AppendLine(string.Format("<div class=\"accordion\" id=\"accordion{0}\">", _fileCount));
            html.AppendLine("<div class=\"accordion-heading\">");
            html.AppendLine(string.Format("<a class=\"accordion-toggle\" data-toggle=\"collapse\" data-parent=\"#accordion{0}\" href=\"#collapse{0}\">",
                                          _fileCount));
            html.AppendLine(
                string.Format("<div class=\"panel-heading\">{0} - Tests: {1} - Failures: <span class=\"{3}\">{2}</span> " +
                              "- Errors: <span class=\"{5}\">{4}</span> - Ignored: <span class=\"{7}\">{6}</span> " +
                              "- Skipped: <span class=\"{9}\">{8}</span></div>",
                              test.Name, test.Tests,
                              test.Failures, test.Failures > 0 ? "text-danger" : string.Empty,
                              test.Errors, test.Errors > 0 ? "text-danger" : string.Empty,
                              test.Ignored, test.Ignored > 0 ? "text-danger" : string.Empty,
                              test.Skipped, test.Skipped > 0 ? "text-danger" : string.Empty));
            html.AppendLine("</a></div>");
            html.AppendLine(string.Format("<div id=\"collapse{0}\" class=\"accordion-body collapse\">", _fileCount));
            html.AppendLine("<div class=\"accordion-inner\">");
            html.AppendLine("<div class=\"row\">");
            html.AppendLine("<div class=\"col-md-12\">");
            html.AppendLine("<div class=\"panel panel-default\">");
            html.AppendLine(string.Format("<div class=\"panel-heading\">Summary - <small>{0}</small></div>", test.Name));
            html.AppendLine("<div class=\"panel-body\">");

            html.Append(AddStatistics(test));

            // End summary panel
            html.AppendLine("</div>");
            html.AppendLine("</div>");
            html.AppendLine("</div>");

            // Process test fixtures
            html.Append(ProcessFixtures(doc.Descendants("test-suite").Where(x => x.Attribute("type").Value == "TestFixture")));

            // End container
            html.AppendLine("</div>");
            html.AppendLine("</div>");
            html.AppendLine("</div>");

            return(html.ToString());
        }
예제 #4
0
        public static TestStats Parse(XElement doc)
        {
            var test = new TestStats();

            test.Name         = doc.Attribute("name").Value;
            test.Tests        = int.Parse(!string.IsNullOrEmpty(doc.Attribute("total").Value) ? doc.Attribute("total").Value : "0");
            test.Errors       = int.Parse(!string.IsNullOrEmpty(doc.Attribute("errors").Value) ? doc.Attribute("errors").Value : "0");
            test.Failures     = int.Parse(!string.IsNullOrEmpty(doc.Attribute("failures").Value) ? doc.Attribute("failures").Value : "0");
            test.NotRun       = int.Parse(!string.IsNullOrEmpty(doc.Attribute("not-run").Value) ? doc.Attribute("not-run").Value : "0");
            test.Inconclusive = int.Parse(!string.IsNullOrEmpty(doc.Attribute("inconclusive").Value) ? doc.Attribute("inconclusive").Value : "0");
            test.Ignored      = int.Parse(!string.IsNullOrEmpty(doc.Attribute("ignored").Value) ? doc.Attribute("ignored").Value : "0");
            test.Skipped      = int.Parse(!string.IsNullOrEmpty(doc.Attribute("skipped").Value) ? doc.Attribute("skipped").Value : "0");
            test.Invalid      = int.Parse(!string.IsNullOrEmpty(doc.Attribute("invalid").Value) ? doc.Attribute("invalid").Value : "0");
            test.Date         = DateTime.Parse(string.Format("{0} {1}", doc.Attribute("date").Value, doc.Attribute("time").Value));
            test.Platform.Append(doc.Element("environment").Attribute("platform").Value);
            return(test);
        }
예제 #5
0
        public static TestStats CalculateFromFixture(XElement doc)
        {
            var test = new TestStats();

            test.Name = doc.Attribute("name").Value;
            var testcases = doc.Descendants("test-case");

            test.Tests        = testcases.Count(x => x.Attribute("executed").Value.ToLower() == "true");
            test.NotRun       = testcases.Count(x => x.Attribute("executed").Value.ToLower() == "false");
            test.Errors       = testcases.Count(x => x.Attribute("result").Value.ToLower() == "error");
            test.Failures     = testcases.Count(x => x.Attribute("result").Value.ToLower() == "failure");
            test.Inconclusive = testcases.Count(x => x.Attribute("result").Value.ToLower() == "inconclusive");
            test.Ignored      = testcases.Count(x => x.Attribute("result").Value.ToLower() == "ignored");
            test.Skipped      = testcases.Count(x => x.Attribute("result").Value.ToLower() == "skipped");
            test.Invalid      = testcases.Count(x => x.Attribute("result").Value.ToLower() == "notrunnable");
            return(test);
        }
        /// <summary>
        /// Process the test fixtures.
        /// </summary>
        /// <param name="fixtures">The test-fixture elements.</param>
        /// <returns>
        /// Fixtures as HTML.
        /// </returns>
        private static string ProcessFixtures(IEnumerable <XElement> fixtures)
        {
            StringBuilder html = new StringBuilder();
            int           index = 0;
            string        fixtureName, fixtureNamespace, fixtureTime, fixtureResult, fixtureReason;

            // Loop through all of the fixtures
            foreach (var fixture in fixtures)
            {
                // Load fixture details
                fixtureName      = fixture.Attribute("name").Value;
                fixtureNamespace = GetElementNamespace(fixture);
                fixtureTime      = fixture.Attribute("time") != null?fixture.Attribute("time").Value : string.Empty;

                fixtureResult = fixture.Attribute("result").Value;
                fixtureReason = fixture.Element("reason") != null?fixture.Element("reason").Element("message").Value : string.Empty;

                html.AppendLine("<div class=\"col-md-3\">");
                html.AppendLine("<div class=\"panel ");

                // Colour code panels
                switch (fixtureResult.ToLower())
                {
                case "success":
                    html.Append("panel-success");
                    break;

                case "ignored":
                    html.Append("panel-info");
                    break;

                case "failure":
                case "error":
                    html.Append("panel-danger");
                    break;

                default:
                    html.Append("panel-default");
                    break;
                }

                html.Append("\">");
                html.AppendLine("<div class=\"panel-heading\">");
                html.AppendLine(string.Format("{0} - <br><small>{1}</small><small class=\"pull-right\">{2}s</small>", fixtureName, fixtureNamespace, fixtureTime));

                // If the fixture has a reason, display an icon
                // on the top of the panel with a tooltip containing
                // the reason
                if (!string.IsNullOrEmpty(fixtureReason))
                {
                    html.AppendLine(string.Format("<span class=\"glyphicon glyphicon-info-sign pull-right info hidden-print\" data-toggle=\"tooltip\" title=\"{0}\"></span>", fixtureReason));
                }

                html.AppendLine("</div>");
                html.AppendLine("<div class=\"panel-body\">");

                html.AppendLine("<div class=\"row\">");
                var test = TestStats.CalculateFromFixture(fixture);
                html.Append(AddStatistics(test, "smallstat", ""));
                html.AppendLine("</div><div class=\"row\">");

                // Generate a unique id for the modal dialog
                string modalId = string.Format("modal-{0}-{1}", Regex.Replace(HttpUtility.UrlEncode(fixtureName), string.Empty), index++);

                html.AppendLine("<div class=\"text-center\" style=\"font-size: 1.5em;\">");

                // Add a colour coded link to the modal dialog
                switch (fixtureResult.ToLower())
                {
                case "success":
                    html.AppendLine(string.Format("<a href=\"#{0}\" role=\"button\" data-toggle=\"modal\" class=\"text-success no-underline\">", modalId));
                    html.AppendLine("<span class=\"glyphicon glyphicon-ok-sign\"></span>");
                    html.AppendLine("<span class=\"test-result\">Success</span>");
                    html.AppendLine("</a>");
                    break;

                case "ignored":
                    html.AppendLine(string.Format("<a href=\"#{0}\" role=\"button\" data-toggle=\"modal\" class=\"text-info no-underline\">", modalId));
                    html.AppendLine("<span class=\"glyphicon glyphicon-info-sign\"></span>");
                    html.AppendLine("<span class=\"test-result\">Ignored</span>");
                    html.AppendLine("</a>");
                    break;

                case "notrunnable":
                    html.AppendLine(string.Format("<a href=\"#{0}\" role=\"button\" data-toggle=\"modal\" class=\"text-default no-underline\">", modalId));
                    html.AppendLine("<span class=\"glyphicon glyphicon-remove-sign\"></span>");
                    html.AppendLine("<span class=\"test-result\">Not Runnable</span>");
                    html.AppendLine("</a>");
                    break;

                case "failure":
                case "error":
                    html.AppendLine(string.Format("<a href=\"#{0}\" role=\"button\" data-toggle=\"modal\" class=\"text-danger no-underline\">", modalId));
                    html.AppendLine("<span class=\"glyphicon glyphicon-exclamation-sign\"></span>");
                    html.AppendLine("<span class=\"test-result\">Failed</span>");
                    html.AppendLine("</a>");
                    break;

                default:
                    break;
                }

                html.AppendLine("</div>");

                // Generate a printable view of the fixtures
                html.AppendLine(GeneratePrintableView(fixture, fixtureReason));

                // Generate the modal dialog that will be shown
                // if the user clicks on the test-fixtures
                html.AppendLine(GenerateFixtureModal(fixture, modalId, fixtureName, fixtureReason));

                html.AppendLine("</div>");
                html.AppendLine("</div>");
                html.AppendLine("</div>");
                html.AppendLine("</div>");
            }

            return(html.ToString());
        }