/// <summary> /// Writes a code representation of a test run's test results. /// This includes all the files for a fully functional test project. /// The generated code files can be used to execute a test run that /// would regenerate the test results. /// </summary> /// <param name="testRun">The test run whose results you want to write to code.</param> /// <param name="rootNamespace">The root namespace to use for generating the project files.</param> /// <param name="directory">The directory to write the files to.</param> public static void WriteFeaturesToCode(this xBDD.Model.TestRun testRun, string rootNamespace, string directory) { ReportingFactory factory = new ReportingFactory(); CodeWriter saver = factory.GetCodeWriter(); saver.WriteFeaturesToCode(testRun, rootNamespace, directory); }
/// <summary> /// Writes a code representation of a test run's test results. /// This includes all the files for a fully functional test project. /// The generated code files can be used to execute a test run that /// would regenerate the test results. /// </summary> /// <param name="testRun">The test run whose results you want to write to code.</param> /// <param name="rootNamespace">The root namespace to use for generating the project files.</param> /// <param name="directory">The directory to write the files to.</param> /// <param name="removeFromCapabilityNameStart">Sets the Remove Capability Name Start setting for xBDD.</param> public static void WriteToCode(this xBDD.Model.TestRun testRun, string rootNamespace, string directory, string removeFromCapabilityNameStart) { ReportingFactory factory = new ReportingFactory(); CodeWriter saver = factory.GetCodeWriter(); saver.WriteToCode(testRun, rootNamespace, directory, removeFromCapabilityNameStart); }
internal TestRun CreateTestRun(xb.TestRun testRun) { return(new TestRun() { Name = testRun.Name }); }
/// <summary> /// Writes a text representation of a test run's test results. /// </summary> /// <param name="testRun">The test run whose results you want to write to text.</param> /// <param name="includeExceptions">Sets the text writer to include /// exceptions for failed steps. Default value is true.</param> /// <returns>String that is a multiline text format of the test results.</returns> public static string WriteToText(this xBDD.Model.TestRun testRun, bool includeExceptions = true) { ReportingFactory factory = new ReportingFactory(); TextWriter saver = factory.GetTextWriter(); return(saver.WriteToText(testRun, includeExceptions)); }
void WriteHtml(TestRun testRun, StringBuilder sb) { sb.AppendLine("<html>"); WriteHeader(testRun, sb); WriteBody(testRun, sb); sb.Append("</html>"); }
/// <summary> /// Writes an OMPL representation of a test run's test results. /// </summary> /// <param name="testRun">The test run whose results you want to write to text.</param> /// <param name="capabilityNameClip">The part to remove from the beginning of each capability name.</param> /// <returns>String that is a OPML format of the test results.</returns> public static string WriteToOpml(this xBDD.Model.TestRun testRun, string capabilityNameClip = null) { ReportingFactory factory = new ReportingFactory(); OpmlWriter saver = factory.GetOpmlWriter(); return(saver.WriteToOpml(testRun, capabilityNameClip)); }
/// <summary> /// Cascades the scenario skipped reasons up the hierarchy. /// Also calculates the count of children for each skipped reason. /// </summary> /// <param name="sortedReasons">The list of reasons sorted from least to highest precedent. /// <param name="sortedFeatureFullNames">The list of feature full name sorted in the order they should appear. /// <param name="testRun">The test run group to update parent reasons and stats for.</param> /// A parent that has both reasons will assume the reason with the highest precedent.</param> public static void CalculateProperties(this xBDD.Model.TestRun testRun, List <string> sortedReasons, List <string> sortedFeatureFullNames) { testRun.CalculateStartAndEndTimes(); testRun.UpdateParentReasonsAndStats(sortedReasons); testRun.UpdateStats(); testRun.SortTestRunResults(sortedFeatureFullNames); }
void WriteBody(TestRun testRun, StringBuilder sb) { WriteTagOpen("body", sb, 0, "container-fluid", false); WriteNavBar(sb); WriteTestRun(testRun, sb); WriteTagClose("body", sb, 0); }
internal static HtmlReportLineItem GetHtmlReportLineItem(this xBDD.Model.TestRun testRun, bool includeChildren) { var li = new HtmlReportLineItem(); li.ChildItems = new List <HtmlReportLineItem>(); li.ChildStats = testRun.CapabilityStats; li.ChildTypeName = "capabilities"; li.EndTime = testRun.EndTime; li.StartTime = testRun.StartTime; li.Name = testRun.Name.HtmlEncode(); li.Outcome = testRun.Outcome; li.Reason = testRun.Reason; li.FilePath = testRun.FilePath; Dictionary <string, Dictionary <string, int> > testRunReasonStatistics = new Dictionary <string, Dictionary <string, int> >(); testRunReasonStatistics.Add("Capabilities", testRun.CapabilityReasonStats); testRunReasonStatistics.Add("Features", testRun.FeatureReasonStats); testRunReasonStatistics.Add("Scenarios", testRun.ScenarioReasonStats); li.ReasonStats = testRunReasonStatistics; li.TypeName = "testrun"; if (includeChildren) { var capabilities = testRun.Capabilities.SelectMany(x => x.Features).OrderBy(x => x.Sort).Select(x => x.Capability).Distinct().ToList(); foreach (var capability in capabilities) { li.ChildItems.Add(capability.GetHtmlReportLineItem()); } } return(li); }
/// <summary> /// Writes a a test run's test results to a sql database. /// </summary> /// <param name="testRun">The test run whose results you want to write to the database.</param> /// <param name="connectionName">The name of the connection string to use to connect to the database.</param> /// <remarks>By default xBDD will look for a connection string in a config.json file or the /// environment variables settings with a name: Data:DefaultConnection:ConnectionString</remarks> /// <returns>Count of scenarios written to the database.</returns> public static int SaveToDatabase(this xBDD.Model.TestRun testRun, string connectionName) { DatabaseFactory factory = new DatabaseFactory(); TestRunDatabaseSaver saver = factory.CreateTestRunDatabaseSaver(connectionName); return(saver.SaveTestRun(testRun)); }
internal TestRun BuildTestRun(xb.TestRun testRun) { var testRunDb = factory.CreateTestRun(testRun); dbContext.TestRuns.Add(testRunDb); BuildScenarios(testRun, testRunDb); return(testRunDb); }
public TestRunBuilder(CoreFactory factory, TestRun testRun) { this.factory = factory; areaCache = factory.CreateAreaCache(); featureCache = factory.CreateFeatureCache(); testRunInitializer = factory.CreateTestRunInitializer(); TestRun = testRun; }
/// <summary> /// Updates the feature, capability, and test outcomes and stats based on the scenario outcomes. /// </summary> public static void UpdateStats(this xBDD.Model.TestRun testRun) { List <Outcome> outcomes = new List <Outcome>() { Outcome.NotRun, Outcome.Passed, Outcome.Skipped, Outcome.Failed }; testRun.Scenarios.ToList().ForEach(scenario => { scenario.Feature.Outcome = Outcome.NotRun; scenario.Feature.Capability.Outcome = Outcome.NotRun; scenario.Feature.Capability.TestRun.Outcome = Outcome.NotRun; scenario.Feature.ScenarioStats.ClearStats(); scenario.Feature.Capability.ScenarioStats.ClearStats(); scenario.Feature.Capability.FeatureStats.ClearStats(); scenario.Feature.Capability.TestRun.ScenarioStats.ClearStats(); scenario.Feature.Capability.TestRun.FeatureStats.ClearStats(); scenario.Feature.Capability.TestRun.CapabilityStats.ClearStats(); }); outcomes.ForEach(outcome => { testRun.Scenarios.SelectMany(x => x.Steps) .Where(step => step.Outcome == outcome) .ToList().ForEach(step => { step.Scenario.Outcome = outcome; step.Scenario.Feature.Outcome = outcome; step.Scenario.Feature.Capability.Outcome = outcome; testRun.Outcome = outcome; }); }); outcomes.ForEach(outcome => { testRun.Scenarios .Where(scenario => scenario.Outcome == outcome && scenario.Steps.Count == 0) .ToList().ForEach(scenario => { scenario.Feature.Outcome = outcome; scenario.Feature.Capability.Outcome = outcome; testRun.Outcome = outcome; }); }); testRun.Capabilities.ForEach(capability => { capability.Features.ForEach(feature => { feature.Scenarios.ForEach(scenario => { feature.ScenarioStats.UpdateOutcomeStats(scenario.Outcome); feature.StepStats.AddStats(scenario.StepStats); }); capability.FeatureStats.UpdateOutcomeStats(feature.Outcome); capability.ScenarioStats.AddStats(feature.ScenarioStats); capability.StepStats.AddStats(feature.StepStats); }); testRun.CapabilityStats.UpdateOutcomeStats(capability.Outcome); testRun.FeatureStats.AddStats(capability.FeatureStats); testRun.ScenarioStats.AddStats(capability.ScenarioStats); testRun.StepStats.AddStats(capability.StepStats); }); }
public void InitializeTestRun(object callingTestClass, TestRun testRun) { if(testRun.Name == null) { var testRunName = callingTestClass.GetType().GetTypeInfo().Assembly.GetCustomAttribute<TestRunNameAttribute>(); if(testRunName != null) testRun.Name = testRunName.GetName(); } }
public Area GetOrCreate(TestRun testRun, string areaName) { var area = areas.Where(x => x.Name == areaName).FirstOrDefault(); if(area == null) { area = factory.CreateArea(areaName, testRun); areas.Add(area); } return area; }
public Task<string> WriteToString(TestRun testRun) { return Task.Run(() => { StringBuilder sb = new StringBuilder(); //sb.AppendLine(JsonConvert.SerializeObject(testRun)); sb.AppendLine("<!DOCTYPE html>"); WriteHtml(testRun, sb); return sb.ToString(); }); }
/// <summary> /// Writes a text representation of a test run's test results. /// </summary> /// <param name="testRun">The test run whose results you want to write to text.</param> /// <param name="config">The report configuration.</param> /// <returns>String that is a multiline text format of the test results.</returns> public static string WriteToHtmlTestRunReport( this xBDD.Model.TestRun testRun, TestRunReportConfiguration config, List <ReportReasonConfiguration> sortedReasons) { ReportingFactory factory = new ReportingFactory(); HtmlTestRunReportWriter saver = factory.GetHtmlTestRunReportWriter(config, sortedReasons); return(saver.WriteToHtmlTestRunReport(testRun)); }
internal Area CreateArea(string name, TestRun testRun) { var area = new Area() { Name = name, TestRun = testRun, FeatureStats = new OutcomeStats(), ScenarioStats = new OutcomeStats(), StepStats = new OutcomeStats() }; testRun.Areas.Add(area); return area; }
private void BuildScenarios(xb.TestRun testRun, TestRun testRunDb) { var scenarios = from capability in testRun.Capabilities from feature in capability.Features from scenario in feature.Scenarios select scenario; foreach (xb.Scenario scenario in scenarios) { Scenario scenarioDb = factory.CreateScenario(scenario, testRunDb); scenarioDb.TestRun = testRunDb; dbContext.Scenarios.Add(scenarioDb); BuildSteps(scenario, scenarioDb); } }
void WriteHeader(TestRun testRun, StringBuilder sb) { sb.AppendLine("<head>"); sb.AppendLine(" <meta charset=\"utf-8\" />"); sb.AppendLine(" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />"); WriteTag("title", sb, 1, null, testRun.Name.HtmlEncode(), true); sb.AppendLine(" <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css\">"); sb.AppendLine(" <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css\">"); WriteStyles(sb); sb.AppendLine(" <script src=\"https://code.jquery.com/jquery-2.1.4.min.js\"></script>"); sb.AppendLine(" <script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js\"></script>"); sb.AppendLine(" <script src=\"https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js?skin=sunburst\"></script>"); sb.AppendLine(" <script language=\"javascript\" type=\"text/javascript\">function resizeIframe(obj) { obj.style.height = obj.contentWindow.document.body.scrollHeight + 'px'; }</script>"); sb.AppendLine("</head>"); }
public async Task<string> WriteToString(TestRun testRun) { return await Task.Run(() => { StringBuilder sb = new StringBuilder(); sb.AppendLine(testRun.Name); sb.AppendLine(); Scenario lastScenario = null; foreach(var scenario in testRun.Scenarios.OrderBy(x => x.Feature.Area.Name).ThenBy(x => x.Feature.Name).ThenBy(x => x.Name)) { WriteScenario(lastScenario, scenario, sb); lastScenario = scenario; } return sb.ToString(); }); }
public static List <ReportReasonConfiguration> GetSortedReasons(this xBDD.Model.TestRun testRun, xBDDConfiguration config) { var reasonConfigs = config.SortedReasonConfigurations.Select(x => x).ToList(); var configuredReasonSortNames = config.SortedReasonConfigurations.Select(x => x.Reason).ToList(); var additionalTestRunReasons = testRun.Scenarios .Where(x => !configuredReasonSortNames.Contains(x.Reason)) .Select(x => x.Reason) .Distinct(); foreach (var additionalReason in additionalTestRunReasons) { reasonConfigs.Insert(0, new ReportReasonConfiguration() { Reason = additionalReason, FontColor = "White", BackgroundColor = "Gray" }); } return(reasonConfigs); }
/// <summary> /// Updates the features sort property. Features are sorted based on the /// list of feature names you provide. Scenarios are sorted based on thier /// sort order that you can provide when creating the scenario xB.AddScenario(this, 1 [sortOrder]) /// </summary> /// <param name="testRun">The test run to sort the features and scenarios.</param> /// <param name="sortedFeatureFullNames">The sorted list of full feature names to use for sorting features. /// Each feature name should be the full name with the namespace included.</param> public static void SortTestRunResults(this xBDD.Model.TestRun testRun, List <string> sortedFeatureFullNames) { var featureIndex = 0; sortedFeatureFullNames.ForEach(featureFullName => { var feature = testRun.Capabilities.SelectMany(x => x.Features).Where(f => f.FullClassName == featureFullName).FirstOrDefault(); if (feature != null) { featureIndex++; feature.Sort = featureIndex; } }); testRun.Capabilities.SelectMany(x => x.Features).Where(x => x.Sort == 0).ToList().ForEach(feature => { feature.Sort = 1000000; }); testRun.Sorted = true; }
/// <summary> /// Writes the test run results to json. /// Only writes the bare minimum properties and does not /// write calculated properties like test stats. /// </summary> /// <param name="testRun">The test run to serialize.</param> /// <param name="addIndentation">Adds indentation to the json.</param> /// <returns>A json string representation of the test results.</returns> public static string WriteToJson(this xBDD.Model.TestRun testRun, bool addIndentation = false) { var json = ""; using (var ms = new System.IO.MemoryStream()) { using (var writer = JsonReaderWriterFactory.CreateJsonWriter(ms, Encoding.UTF8, true, addIndentation)) { var currentCulture = Thread.CurrentThread.CurrentCulture; Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; try { DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Model.TestRun)); ser.WriteObject(writer, testRun); writer.Flush(); byte[] jsonBytes = ms.ToArray(); json = Encoding.UTF8.GetString(jsonBytes, 0, jsonBytes.Length); } finally { Thread.CurrentThread.CurrentCulture = currentCulture; } } } return(json); }
/// <summary> /// Cascades the scenario skipped reasons up the hierarchy. /// Also calculates the count of children for each skipped reason. /// </summary> /// <param name="sortedReasons">The list of reasons sorted from least to highest precedent. /// <param name="testRun">The test run to update parent reasons and stats for.</param> /// A parent that has both reasons will assume the reason with the highest precedent.</param> public static void UpdateParentReasonsAndStats(this xBDD.Model.TestRun testRun, List <string> sortedReasons) { testRun.CapabilityReasonStats.Clear(); testRun.FeatureReasonStats.Clear(); testRun.ScenarioReasonStats.Clear(); testRun.Capabilities.ForEach(capability => { capability.FeatureReasonStats.Clear(); capability.ScenarioReasonStats.Clear(); capability.Features.ForEach(feature => { feature.ScenarioReasonStats.Clear(); }); }); if (!sortedReasons.Contains("Failed")) { sortedReasons.Add("Failed"); } testRun.Scenarios.ForEach(scenario => { scenario.Steps.ForEach(step => { switch (step.Reason) { case "Passed": scenario.Reason = "Passed"; break; case "Previous Error": scenario.Reason = "Failed"; break; case "Scenario Skipped": // do nothing because reason would be set when the scenario was skipped. break; case "Failed": scenario.Reason = "Failed"; break; } }); }); var additionalScenarioReasons = testRun.Scenarios .Select(scenario => scenario.Reason) .Where(reason => !sortedReasons.Contains(reason) && reason != null) .Distinct() .OrderBy(reason => reason) .ToList(); sortedReasons.InsertRange(0, additionalScenarioReasons.Distinct()); // var additionalStepReasons = testRun.Scenarios.SelectMany(x => x.Steps) // .Select(step => step.Reason) // .Distinct() // .Where(reason => !sortedReasons.Contains(reason) && reason != null) // .OrderBy(reason => reason) // .ToList(); // sortedReasons.InsertRange(0,additionalStepReasons); sortedReasons.ForEach(reason => { testRun.Scenarios .Where(scenario => scenario.Reason == reason) .ToList().ForEach(scenario => { scenario.Feature.Reason = reason; if (scenario.Feature.ScenarioReasonStats.Keys.Contains(reason)) { scenario.Feature.ScenarioReasonStats[reason] = scenario.Feature.ScenarioReasonStats[reason] + 1; } else { scenario.Feature.ScenarioReasonStats.Add(reason, 1); } scenario.Feature.Capability.Reason = reason; if (scenario.Feature.Capability.ScenarioReasonStats.Keys.Contains(reason)) { scenario.Feature.Capability.ScenarioReasonStats[reason] = scenario.Feature.Capability.ScenarioReasonStats[reason] + 1; } else { scenario.Feature.Capability.ScenarioReasonStats.Add(reason, 1); } testRun.Reason = reason; if (testRun.ScenarioReasonStats.Keys.Contains(reason)) { testRun.ScenarioReasonStats[reason] = testRun.ScenarioReasonStats[reason] + 1; } else { testRun.ScenarioReasonStats.Add(reason, 1); } }); }); sortedReasons.ForEach(reason => { testRun.Scenarios .Where(scenario => scenario.Feature.Reason == reason) .Select(scenario => scenario.Feature) .Distinct() .ToList() .ForEach(feature => { if (feature.Capability.FeatureReasonStats.Keys.Contains(reason)) { feature.Capability.FeatureReasonStats[reason] = feature.Capability.FeatureReasonStats[reason] + 1; } else { feature.Capability.FeatureReasonStats.Add(reason, 1); } if (testRun.FeatureReasonStats.Keys.Contains(reason)) { testRun.FeatureReasonStats[reason] = testRun.FeatureReasonStats[reason] + 1; } else { testRun.FeatureReasonStats.Add(reason, 1); } }); }); sortedReasons.ForEach(reason => { testRun.Capabilities .Where(capability => capability.Reason == reason) .ToList().ForEach(capability => { if (testRun.CapabilityReasonStats.Keys.Contains(reason)) { testRun.CapabilityReasonStats[reason] = testRun.CapabilityReasonStats[reason] + 1; } else { testRun.CapabilityReasonStats.Add(reason, 1); } }); }); }
/// <summary> /// Calculates the start and end time for the test run, /// capabilities, and features. /// </summary> /// <param name="testrun">The test run to set the start and end times for.</param> public static void CalculateStartAndEndTimes(this xBDD.Model.TestRun testrun) { testrun.Capabilities.SelectMany(x => x.Features).SelectMany(x => x.Scenarios).ToList() .ForEach(scenario => { if (scenario.Steps.Count > 0) { var earliest = scenario.Steps .OrderBy(step => step.StartTime) .Where(x => !DateTime.Equals(x.StartTime, System.DateTime.MinValue)) .FirstOrDefault(); if (earliest != null) { scenario.StartTime = earliest.StartTime; } var latest = scenario.Steps .OrderByDescending(step => step.EndTime) .Where(x => !DateTime.Equals(x.StartTime, System.DateTime.MinValue)) .FirstOrDefault(); if (latest != null) { scenario.EndTime = latest.StartTime; } } }); testrun.Capabilities.SelectMany(x => x.Features).ToList().ForEach(feature => { var earliest = feature.Scenarios .OrderBy(scenario => scenario.StartTime) .Where(x => !DateTime.Equals(x.StartTime, System.DateTime.MinValue)) .FirstOrDefault(); if (earliest != null) { feature.StartTime = earliest.StartTime; } var latest = feature.Scenarios .OrderByDescending(scenario => scenario.EndTime) .Where(x => !DateTime.Equals(x.StartTime, System.DateTime.MinValue)) .FirstOrDefault(); if (latest != null) { feature.EndTime = latest.StartTime; } }); testrun.Capabilities.ToList().ForEach(capability => { var earliest = capability.Features .OrderBy(feature => feature.StartTime) .Where(x => !DateTime.Equals(x.StartTime, System.DateTime.MinValue)) .FirstOrDefault(); if (earliest != null) { capability.StartTime = earliest.StartTime; } var latest = capability.Features .OrderByDescending(feature => feature.EndTime) .Where(x => !DateTime.Equals(x.StartTime, System.DateTime.MinValue)) .FirstOrDefault(); if (latest != null) { capability.EndTime = latest.StartTime; } }); if (testrun.Capabilities.Count > 0) { var earliest = testrun.Capabilities. OrderBy(capability => capability.StartTime) .Where(x => !DateTime.Equals(x.StartTime, System.DateTime.MinValue)) .FirstOrDefault(); if (earliest != null) { testrun.StartTime = earliest.StartTime; } var latest = testrun.Capabilities .OrderByDescending(capability => capability.EndTime) .Where(x => !DateTime.Equals(x.StartTime, System.DateTime.MinValue)) .FirstOrDefault(); if (latest != null) { testrun.EndTime = latest.StartTime; } } }
private void WriteTestRun(TestRun testRun, StringBuilder sb) { var scenarioCount = testRun.Areas.Count; var cssClass = "testrun-name"; if (scenarioCount == 0) { cssClass = cssClass + " text-muted"; } else { switch (testRun.Outcome) { case Outcome.Failed: cssClass = cssClass + " text-danger"; break; case Outcome.NotRun: cssClass = cssClass + " text-info"; break; case Outcome.Passed: cssClass = cssClass + " text-success"; break; case Outcome.Skipped: cssClass = cssClass + " text-warning"; break; } } WriteTagOpen("div", sb, 1, "page-header", false, null, "margin-top: 0px !important;"); WriteTagOpen("h1", sb, 2, cssClass, true); WriteTag("small", sb, 2, null, "Test Run", true); sb.Append("</br>"); WriteTag("span", sb, 0, "name", testRun.Name.HtmlEncode(), true); WriteTag("span", sb, 0, "badge pull-right total", testRun.AreaStats.Total.ToString(), true, null, null, "title=\"Areas\""); WriteTagClose("h1", sb, 2); WriteTagClose("div", sb, 1); WriteStatsTableStart(sb, 1); WriteStats(sb, testRun.AreaStats, 1, "testrun-area-stats", "Areas"); WriteStats(sb, testRun.FeatureStats, 1, "testrun-feature-stats", "Features"); WriteStats(sb, testRun.ScenarioStats, 1, "testrun-scenario-stats", "Scenarios"); WriteStatsTableClose(sb, 1); if (scenarioCount > 0) { WriteAreas(testRun, sb); } }
void WriteAreas(TestRun testRun, StringBuilder sb) { WriteTagOpen("ol", sb, 1, "areas list-unstyled", false); Scenario lastScenario = null; foreach (var scenario in testRun.Scenarios.OrderBy(x => x.Feature.Area.Name).ThenBy(x => x.Feature.Name).ThenBy(x => x.Name)) { WriteAreaFeatureAndScenario(lastScenario, scenario, sb); lastScenario = scenario; } WriteFeatureClose(sb); WriteAreaClose(sb); WriteTagClose("ol", sb, 1);//areas }