public HostedAppxTest(string[] args, XunitProject project, string runnerAppxPath, string installPath) { this.originalArgs = args; this.project = project; this.runnerAppxPath = runnerAppxPath; this.InstallLocation = installPath; NativeMethods.CoInitializeEx(IntPtr.Zero, 2); }
public HostedAppxTest(string[] args, XunitProject project, string runnerAppxPath, string installPath) { this.originalArgs = args; this.project = project; this.runnerAppxPath = runnerAppxPath; this.InstallLocation = installPath; this.PackageSourceDirectory = Environment.GetEnvironmentVariable("HELIX_CORRELATION_PAYLOAD"); NativeMethods.CoInitializeEx(IntPtr.Zero, 2); }
static XunitProject GetProjectFile(List<Tuple<string, string>> assemblies) { var result = new XunitProject(); foreach (var assembly in assemblies) result.Add(new XunitProjectAssembly { AssemblyFilename = Path.GetFullPath(assembly.Item1), ConfigFilename = assembly.Item2 != null ? Path.GetFullPath(assembly.Item2) : null, }); return result; }
static int RunProject(XunitProject project, bool teamcity, bool silent) { int totalAssemblies = 0; int totalTests = 0; int totalFailures = 0; int totalSkips = 0; double totalTime = 0; var mate = new MultiAssemblyTestEnvironment(); foreach (XunitProjectAssembly assembly in project.Assemblies) { TestAssembly testAssembly = mate.Load(assembly.AssemblyFilename, assembly.ConfigFilename, assembly.ShadowCopy); List<IResultXmlTransform> transforms = TransformFactory.GetAssemblyTransforms(assembly); Console.WriteLine(); Console.WriteLine("xunit.dll: Version {0}", testAssembly.XunitVersion); Console.WriteLine("Test assembly: {0}", testAssembly.AssemblyFilename); Console.WriteLine(); try { var methods = new List<TestMethod>(testAssembly.EnumerateTestMethods(project.Filters.Filter)); if (methods.Count == 0) { Console.WriteLine("Skipping assembly (no tests match the specified filter)."); continue; } var callback = teamcity ? (RunnerCallback)new TeamCityRunnerCallback() : new StandardRunnerCallback(silent, methods.Count); var assemblyXml = testAssembly.Run(methods, callback); ++totalAssemblies; totalTests += callback.TotalTests; totalFailures += callback.TotalFailures; totalSkips += callback.TotalSkips; totalTime += callback.TotalTime; foreach (var transform in transforms) transform.Transform(assemblyXml); } catch (ArgumentException ex) { Console.WriteLine(ex.Message); } mate.Unload(testAssembly); } if (!teamcity && totalAssemblies > 1) { Console.WriteLine(); Console.WriteLine("=== {0} total, {1} failed, {2} skipped, took {3} seconds ===", totalTests, totalFailures, totalSkips, totalTime.ToString("0.000", CultureInfo.InvariantCulture)); } return totalFailures; }
void LoadProject(string filename) { var splash = new LoaderForm(); try { splash.Show(); splash.Update(); UnloadAssemblies(listAssemblies.Items); listAssemblies.Update(); project = XunitProject.Load(filename); mruProjectList.Add(filename); foreach (XunitProjectAssembly assembly in project.Assemblies) AddTestAssembly(mate.Load(assembly.AssemblyFilename, assembly.ConfigFilename, assembly.ShadowCopy)); } catch (Exception ex) { MessageBox.Show("Error loading project:\r\n\r\n" + ex.Message, windowTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { splash.Close(); splash.Dispose(); } UpdateAssemblyDynamicMenus(); UpdateProjectDynamicMenus(); }
public override bool Execute() { RemotingUtility.CleanUpRegisteredChannels(); if (TeamCity) { Log.LogError("The 'TeamCity' property is deprecated. Please set the 'Reporter' property to 'teamcity' instead."); return false; } if (Verbose) { Log.LogError("The 'Verbose' property is deprecated. Please set the 'Reporter' property to 'verbose' instead."); return false; } XElement assembliesElement = null; var environment = string.Format("{0}-bit .NET {1}", IntPtr.Size * 8, Environment.Version); if (NeedsXml) assembliesElement = new XElement("assemblies"); switch (MaxParallelThreads) { case null: case "default": break; case "unlimited": maxThreadCount = 0; break; default: int threadValue; if (!int.TryParse(MaxParallelThreads, out threadValue) || threadValue < 0) { Log.LogError("MaxParallelThreads value '{0}' is invalid: must be 'default', 'unlimited', or a positive number", MaxParallelThreads); return false; } maxThreadCount = threadValue; break; } var originalWorkingFolder = Directory.GetCurrentDirectory(); using (AssemblyHelper.SubscribeResolve()) { var reporters = GetAvailableRunnerReporters(); var reporter = reporters.FirstOrDefault(r => r.IsEnvironmentallyEnabled); if (reporter == null && !string.IsNullOrWhiteSpace(Reporter)) { reporter = reporters.FirstOrDefault(r => string.Equals(r.RunnerSwitch, Reporter, StringComparison.OrdinalIgnoreCase)); if (reporter == null) { var switchableReporters = reporters.Where(r => !string.IsNullOrWhiteSpace(r.RunnerSwitch)).Select(r => r.RunnerSwitch.ToLowerInvariant()).OrderBy(x => x).ToList(); if (switchableReporters.Count == 0) Log.LogError("Reporter value '{0}' is invalid. There are no available reporters.", Reporter); else Log.LogError("Reporter value '{0}' is invalid. Available reporters: {1}", Reporter, string.Join(", ", switchableReporters)); return false; } } if (reporter == null) reporter = new DefaultRunnerReporter(); logger = new MSBuildLogger(Log); reporterMessageHandler = reporter.CreateMessageHandler(logger); if (!NoLogo) Log.LogMessage(MessageImportance.High, "xUnit.net MSBuild Runner ({0})", environment); var project = new XunitProject(); foreach (var assembly in Assemblies) { var assemblyFileName = assembly.GetMetadata("FullPath"); var configFileName = assembly.GetMetadata("ConfigFile"); if (configFileName != null && configFileName.Length == 0) configFileName = null; project.Add(new XunitProjectAssembly { AssemblyFilename = assemblyFileName, ConfigFilename = configFileName, ShadowCopy = ShadowCopy }); } if (WorkingFolder != null) Directory.SetCurrentDirectory(WorkingFolder); var clockTime = Stopwatch.StartNew(); if (!parallelizeAssemblies.HasValue) parallelizeAssemblies = project.All(assembly => assembly.Configuration.ParallelizeAssemblyOrDefault); if (parallelizeAssemblies.GetValueOrDefault()) { var tasks = project.Assemblies.Select(assembly => Task.Run(() => ExecuteAssembly(assembly))); var results = Task.WhenAll(tasks).GetAwaiter().GetResult(); foreach (var assemblyElement in results.Where(result => result != null)) assembliesElement.Add(assemblyElement); } else { foreach (var assembly in project.Assemblies) { var assemblyElement = ExecuteAssembly(assembly); if (assemblyElement != null) assembliesElement.Add(assemblyElement); } } clockTime.Stop(); if (completionMessages.Count > 0) reporterMessageHandler.OnMessage(new TestExecutionSummary(clockTime.Elapsed, completionMessages.OrderBy(kvp => kvp.Key).ToList())); } Directory.SetCurrentDirectory(WorkingFolder ?? originalWorkingFolder); if (NeedsXml) { if (Xml != null) assembliesElement.Save(Xml.GetMetadata("FullPath")); if (XmlV1 != null) Transform("xUnit1.xslt", assembliesElement, XmlV1); if (Html != null) Transform("HTML.xslt", assembliesElement, Html); if (NUnit != null) Transform("NUnitXml.xslt", assembliesElement, NUnit); } return ExitCode == 0; }
static XunitProject GetSingleAssemblyProject(string assemblyFile, string configFile) { XunitProject project = new XunitProject(); project.AddAssembly( new XunitProjectAssembly { AssemblyFilename = assemblyFile, ConfigFilename = configFile, ShadowCopy = true } ); return project; }
static int RunProject(XunitProject project, bool teamcity, bool silent) { int totalAssemblies = 0; int totalTests = 0; int totalFailures = 0; int totalSkips = 0; double totalTime = 0; foreach (XunitProjectAssembly assembly in project.Assemblies) using (ExecutorWrapper wrapper = new ExecutorWrapper(assembly.AssemblyFilename, assembly.ConfigFilename, assembly.ShadowCopy)) { Console.WriteLine(); Console.WriteLine("xunit.dll: Version {0}", wrapper.XunitVersion); Console.WriteLine("Test assembly: {0}", Path.GetFullPath(assembly.AssemblyFilename)); Console.WriteLine(); try { List<IResultXmlTransform> transforms = TransformFactory.GetAssemblyTransforms(assembly); Logger logger = teamcity ? (Logger)new TeamCityLogger() : new StandardLogger(silent, wrapper.GetAssemblyTestCount()); new TestRunner(wrapper, logger).RunAssembly(transforms); ++totalAssemblies; totalTests += logger.TotalTests; totalFailures += logger.TotalFailures; totalSkips += logger.TotalSkips; totalTime += logger.TotalTime; } catch (ArgumentException ex) { Console.WriteLine(ex.Message); } } if (!teamcity && totalAssemblies > 1) { Console.WriteLine(); Console.WriteLine("=== {0} total, {1} failed, {2} skipped, took {3} seconds ===", totalTests, totalFailures, totalSkips, totalTime.ToString("0.000", CultureInfo.InvariantCulture)); } return totalFailures; }
static int RunProject(XunitProject project, bool serialize, bool?parallelizeAssemblies, bool?parallelizeTestCollections, int?maxThreadCount, bool diagnosticMessages, bool noColor, bool?noAppDomain) { XElement assembliesElement = null; var clockTime = Stopwatch.StartNew(); var xmlTransformers = TransformFactory.GetXmlTransformers(project); var needsXml = xmlTransformers.Count > 0; var consoleLock = new object(); if (!parallelizeAssemblies.HasValue) { parallelizeAssemblies = project.All(assembly => assembly.Configuration.ParallelizeAssemblyOrDefault); } if (needsXml) { assembliesElement = new XElement("assemblies"); } var originalWorkingFolder = Directory.GetCurrentDirectory(); using (AssemblyHelper.SubscribeResolve()) { if (parallelizeAssemblies.GetValueOrDefault()) { var tasks = project.Assemblies.Select(assembly => Task.Run(() => ExecuteAssembly(consoleLock, assembly, serialize, needsXml, parallelizeTestCollections, maxThreadCount, diagnosticMessages, noColor, noAppDomain, project.Filters))); var results = Task.WhenAll(tasks).GetAwaiter().GetResult(); foreach (var assemblyElement in results.Where(result => result != null)) { assembliesElement.Add(assemblyElement); } } else { foreach (var assembly in project.Assemblies) { var assemblyElement = ExecuteAssembly(consoleLock, assembly, serialize, needsXml, parallelizeTestCollections, maxThreadCount, diagnosticMessages, noColor, noAppDomain, project.Filters); if (assemblyElement != null) { assembliesElement.Add(assemblyElement); } } } clockTime.Stop(); if (completionMessages.Count > 0) { reporterMessageHandler.OnMessage(new TestExecutionSummary(clockTime.Elapsed, completionMessages.OrderBy(kvp => kvp.Key).ToList())); } } Directory.SetCurrentDirectory(originalWorkingFolder); xmlTransformers.ForEach(transformer => transformer(assembliesElement)); return(failed ? 1 : completionMessages.Values.Sum(summary => summary.Failed)); }
public void NullFilenameThrows() { Assert.Throws <ArgumentNullException>(() => XunitProject.Load(null)); }
public void ProjectIsNotDirtyToStart() { XunitProject project = new XunitProject(); Assert.False(project.IsDirty); }
public void NullFilenameThrows() { XunitProject project = new XunitProject(); Assert.Throws <ArgumentNullException>(() => project.Filename = null); }
public void NullAssemblyThrows() { XunitProject project = new XunitProject(); Assert.Throws <ArgumentNullException>(() => project.RemoveAssembly(null)); }
public void InvalidXmlFormatThrows() { using (TempFile tempFile = new TempFile("<invalid />")) Assert.Throws <ArgumentException>(() => XunitProject.Load(tempFile.Filename)); }
public void InvalidFilenameThrows() { Assert.Throws <FileNotFoundException>( () => XunitProject.Load(Guid.NewGuid().ToString())); }
/* * private void PrintUsage(IReadOnlyList<IRunnerReporter> reporters) * { * var executableName = Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().GetLocalCodeBase()); * * // NET Core * ////var executableName = "dotnet xunit"; * * Console.WriteLine("Copyright (C) .NET Foundation."); * Console.WriteLine(); * Console.WriteLine($"usage: {executableName} <assemblyFile> [configFile] [assemblyFile [configFile]...] [options] [reporter] [resultFormat filename [...]]"); * Console.WriteLine(); #if NET452 * Console.WriteLine("Note: Configuration files must end in .json (for JSON) or .config (for XML)"); #else * Console.WriteLine("Note: Configuration files must end in .json (XML is not supported on .NET Core)"); #endif * Console.WriteLine(); * Console.WriteLine("Valid options:"); * Console.WriteLine(" -nologo : do not show the copyright message"); * Console.WriteLine(" -nocolor : do not output results with colors"); #if NET452 * Console.WriteLine(" -noappdomain : do not use app domains to run test code"); #endif * Console.WriteLine(" -failskips : convert skipped tests into failures"); * Console.WriteLine(" -stoponfail : stop on first test failure"); * Console.WriteLine(" -parallel option : set parallelization based on option"); * Console.WriteLine(" : none - turn off all parallelization"); * Console.WriteLine(" : collections - only parallelize collections"); * Console.WriteLine(" : assemblies - only parallelize assemblies"); * Console.WriteLine(" : all - parallelize assemblies & collections"); * Console.WriteLine(" -maxthreads count : maximum thread count for collection parallelization"); * Console.WriteLine(" : default - run with default (1 thread per CPU thread)"); * Console.WriteLine(" : unlimited - run with unbounded thread count"); * Console.WriteLine(" : (number) - limit task thread pool size to 'count'"); #if NET452 * Console.WriteLine(" -noshadow : do not shadow copy assemblies"); #endif * Console.WriteLine(" -wait : wait for input after completion"); * Console.WriteLine(" -diagnostics : enable diagnostics messages for all test assemblies"); * Console.WriteLine(" -internaldiagnostics : enable internal diagnostics messages for all test assemblies"); #if DEBUG * Console.WriteLine(" -pause : pause before doing any work, to help attach a debugger"); #endif * Console.WriteLine(" -debug : launch the debugger to debug the tests"); * Console.WriteLine(" -serialize : serialize all test cases (for diagnostic purposes only)"); * Console.WriteLine(" -trait \"name=value\" : only run tests with matching name/value traits"); * Console.WriteLine(" : if specified more than once, acts as an OR operation"); * Console.WriteLine(" -notrait \"name=value\" : do not run tests with matching name/value traits"); * Console.WriteLine(" : if specified more than once, acts as an AND operation"); * Console.WriteLine(" -method \"name\" : run a given test method (can be fully specified or use a wildcard;"); * Console.WriteLine(" : i.e., 'MyNamespace.MyClass.MyTestMethod' or '*.MyTestMethod')"); * Console.WriteLine(" : if specified more than once, acts as an OR operation"); * Console.WriteLine(" -class \"name\" : run all methods in a given test class (should be fully"); * Console.WriteLine(" : specified; i.e., 'MyNamespace.MyClass')"); * Console.WriteLine(" : if specified more than once, acts as an OR operation"); * Console.WriteLine(" -namespace \"name\" : run all methods in a given namespace (i.e.,"); * Console.WriteLine(" : 'MyNamespace.MySubNamespace')"); * Console.WriteLine(" : if specified more than once, acts as an OR operation"); * Console.WriteLine(" -noautoreporters : do not allow reporters to be auto-enabled by environment"); * Console.WriteLine(" : (for example, auto-detecting TeamCity or AppVeyor)"); #if NETCOREAPP1_0 || NETCOREAPP2_0 * Console.WriteLine(" -framework \"name\" : set the target framework"); #endif * Console.WriteLine(); * * var switchableReporters = reporters.Where(r => !string.IsNullOrWhiteSpace(r.RunnerSwitch)).ToList(); * if (switchableReporters.Count > 0) * { * Console.WriteLine("Reporters: (optional, choose only one)"); * * foreach (var reporter in switchableReporters.OrderBy(r => r.RunnerSwitch)) * { * Console.WriteLine($" -{reporter.RunnerSwitch.ToLowerInvariant().PadRight(21)} : {reporter.Description}"); * } * * Console.WriteLine(); * } * * Console.WriteLine("Result formats: (optional, choose one or more)"); * TransformFactory.AvailableTransforms.ForEach( * transform => Console.WriteLine($" -{$"{transform.CommandLine} <filename>".PadRight(21).Substring(0, 21)} : {transform.Description}") * ); * } */ private int RunProject([NotNull] TestRunOptions options) { if (options == null) { throw new ArgumentNullException(nameof(options)); } XunitProject project = options.Project; bool?parallelizeAssemblies = options.ParallelizeAssemblies; XElement assembliesElement = null; var clockTime = Stopwatch.StartNew(); var xmlTransformers = TransformFactory.GetXmlTransformers(project); var needsXml = xmlTransformers.Count > 0; if (!parallelizeAssemblies.HasValue) { parallelizeAssemblies = project.All(assembly => assembly.Configuration.ParallelizeAssemblyOrDefault); } if (needsXml) { assembliesElement = new XElement("assemblies"); } var originalWorkingFolder = Directory.GetCurrentDirectory(); if (parallelizeAssemblies.GetValueOrDefault()) { var tasks = project.Assemblies.Select( assembly => Task.Run( () => ExecuteAssembly( assembly, options, needsXml, project.Filters))); var results = Task.WhenAll(tasks).GetAwaiter().GetResult(); if (assembliesElement != null) { foreach (var assemblyElement in results.Where(result => result != null)) { assembliesElement.Add(assemblyElement); } } } else { foreach (var assembly in project.Assemblies) { var assemblyElement = ExecuteAssembly( assembly, options, needsXml, project.Filters); assembliesElement?.Add(assemblyElement); } } clockTime.Stop(); assembliesElement?.Add(new XAttribute("timestamp", DateTime.Now.ToString(CultureInfo.InvariantCulture))); if (_completionMessages.Count > 0) { _reporterMessageHandler.OnMessage(new TestExecutionSummary(clockTime.Elapsed, _completionMessages.OrderBy(kvp => kvp.Key).ToList())); } Directory.SetCurrentDirectory(originalWorkingFolder); xmlTransformers.ForEach(transformer => transformer(assembliesElement)); return(_failed ? 1 : _completionMessages.Values.Sum(summary => summary.Failed)); }
static void GuardNoProjectFile(XunitProject project, KeyValuePair<string, string> option) { if (project != null) throw new ArgumentException(String.Format("the {0} command line option isn't valid for .xunit projects", option.Key)); }
public static List <Action <XElement> > GetXmlTransformers([NotNull][ItemNotNull] XunitProject project) => project.Output .Select(output => new Action <XElement>(xml => Instance._availableTransforms[output.Key].OutputHandler(xml, output.Value))) .ToList();
public static List <Action <XElement> > GetXmlTransformers(XunitProject project) { return(project.Output.Select(output => new Action <XElement>(xml => instance.availableTransforms[output.Key].OutputHandler(xml, output.Value))).ToList()); }
static int RunProject(string defaultDirectory, XunitProject project, bool teamcity, bool silent, bool parallelizeAssemblies, bool parallelizeTestCollections, int maxThreadCount) { XElement assembliesElement = null; var xmlTransformers = TransformFactory.GetXmlTransformers(project); var needsXml = xmlTransformers.Count > 0; var consoleLock = new object(); if (needsXml) { assembliesElement = new XElement("assemblies"); } string originalWorkingFolder = Directory.GetCurrentDirectory(); using (AssemblyHelper.SubscribeResolve()) { if (parallelizeAssemblies) { var tasks = project.Assemblies.Select(assembly => Task.Run(() => ExecuteAssembly(consoleLock, defaultDirectory, assembly, needsXml, teamcity, silent, parallelizeTestCollections, maxThreadCount, project.Filters))); var results = Task.WhenAll(tasks).GetAwaiter().GetResult(); foreach (var assemblyElement in results.Where(result => result != null)) { assembliesElement.Add(assemblyElement); } } else { foreach (var assembly in project.Assemblies) { var assemblyElement = ExecuteAssembly(consoleLock, defaultDirectory, assembly, needsXml, teamcity, silent, parallelizeTestCollections, maxThreadCount, project.Filters); if (assemblyElement != null) { assembliesElement.Add(assemblyElement); } } } if (completionMessages.Count > 0) { Console.ForegroundColor = ConsoleColor.White; Console.WriteLine(); Console.WriteLine("=== TEST EXECUTION SUMMARY ==="); Console.ForegroundColor = ConsoleColor.Gray; int longestAssemblyName = completionMessages.Keys.Max(key => key.Length); int longestTotal = completionMessages.Values.Max(summary => summary.Total.ToString().Length); int longestFailed = completionMessages.Values.Max(summary => summary.Failed.ToString().Length); int longestSkipped = completionMessages.Values.Max(summary => summary.Skipped.ToString().Length); int longestTime = completionMessages.Values.Max(summary => summary.Time.ToString("0.000s").Length); foreach (var message in completionMessages.OrderBy(m => m.Key)) { Console.WriteLine(" {0} Total: {1}, Failed: {2}, Skipped: {3}, Time: {4}", message.Key.PadRight(longestAssemblyName), message.Value.Total.ToString().PadLeft(longestTotal), message.Value.Failed.ToString().PadLeft(longestFailed), message.Value.Skipped.ToString().PadLeft(longestSkipped), message.Value.Time.ToString("0.000s").PadLeft(longestTime)); } } } Directory.SetCurrentDirectory(originalWorkingFolder); xmlTransformers.ForEach(transformer => transformer(assembliesElement)); return(failed ? 1 : completionMessages.Values.Sum(summary => summary.Failed)); }
public override bool Execute() { RemotingUtility.CleanUpRegisteredChannels(); XElement assembliesElement = null; var environment = $"{IntPtr.Size * 8}-bit {CrossPlatform.Version}"; if (NeedsXml) { assembliesElement = new XElement("assemblies"); } switch (MaxParallelThreads) { case null: case "default": break; case "unlimited": maxThreadCount = -1; break; default: int threadValue; if (!int.TryParse(MaxParallelThreads, out threadValue) || threadValue < 1) { Log.LogError("MaxParallelThreads value '{0}' is invalid: must be 'default', 'unlimited', or a positive number", MaxParallelThreads); return(false); } maxThreadCount = threadValue; break; } var originalWorkingFolder = Directory.GetCurrentDirectory(); using (AssemblyHelper.SubscribeResolve()) { var reporter = GetReporter(); if (reporter == null) { return(false); } logger = new MSBuildLogger(Log); reporterMessageHandler = MessageSinkWithTypesAdapter.Wrap(reporter.CreateMessageHandler(logger)); if (!NoLogo) { Log.LogMessage(MessageImportance.High, "xUnit.net MSBuild Runner ({0})", environment); } var project = new XunitProject(); foreach (var assembly in Assemblies) { var assemblyFileName = assembly.GetMetadata("FullPath"); var configFileName = assembly.GetMetadata("ConfigFile"); if (configFileName != null && configFileName.Length == 0) { configFileName = null; } var projectAssembly = new XunitProjectAssembly { AssemblyFilename = assemblyFileName, ConfigFilename = configFileName }; if (shadowCopy.HasValue) { projectAssembly.Configuration.ShadowCopy = shadowCopy; } project.Add(projectAssembly); } if (WorkingFolder != null) { Directory.SetCurrentDirectory(WorkingFolder); } var clockTime = Stopwatch.StartNew(); if (!parallelizeAssemblies.HasValue) { parallelizeAssemblies = project.All(assembly => assembly.Configuration.ParallelizeAssemblyOrDefault); } if (parallelizeAssemblies.GetValueOrDefault()) { var tasks = project.Assemblies.Select(assembly => Task.Run(() => ExecuteAssembly(assembly))); var results = Task.WhenAll(tasks).GetAwaiter().GetResult(); foreach (var assemblyElement in results.Where(result => result != null)) { assembliesElement.Add(assemblyElement); } } else { foreach (var assembly in project.Assemblies) { var assemblyElement = ExecuteAssembly(assembly); if (assemblyElement != null) { assembliesElement.Add(assemblyElement); } } } clockTime.Stop(); if (assembliesElement != null) { assembliesElement.Add(new XAttribute("timestamp", DateTime.Now.ToString(CultureInfo.InvariantCulture))); } if (completionMessages.Count > 0) { reporterMessageHandler.OnMessage(new TestExecutionSummary(clockTime.Elapsed, completionMessages.OrderBy(kvp => kvp.Key).ToList())); } } Directory.SetCurrentDirectory(WorkingFolder ?? originalWorkingFolder); if (NeedsXml) { if (Xml != null) { assembliesElement.Save(new FileStream(Xml.GetMetadata("FullPath"), FileMode.OpenOrCreate)); } if (XmlV1 != null) { CrossPlatform.Transform(logger, "XmlV1", "xUnit1.xslt", assembliesElement, XmlV1); } if (Html != null) { CrossPlatform.Transform(logger, "Html", "HTML.xslt", assembliesElement, Html); } if (NUnit != null) { CrossPlatform.Transform(logger, "NUnit", "NUnitXml.xslt", assembliesElement, NUnit); } } // ExitCode is set to 1 for test failures and -1 for Exceptions. return(ExitCode == 0 || (ExitCode == 1 && IgnoreFailures)); }
int RunProject(XunitProject project, bool?parallelizeAssemblies, bool?parallelizeTestCollections, int?maxThreadCount, bool diagnosticMessages, bool noColor, bool designTime, bool list, IReadOnlyList <string> designTimeFullyQualifiedNames) { XElement assembliesElement = null; var xmlTransformers = TransformFactory.GetXmlTransformers(project); var needsXml = xmlTransformers.Count > 0; var consoleLock = new object(); if (!parallelizeAssemblies.HasValue) { parallelizeAssemblies = project.All(assembly => { var assm = (XunitProjectAssembly2)assembly; return(assm.ConfigFilename != null ? assm.Configuration.ParallelizeAssemblyOrDefault : assm.ConfigurationStream.ParallelizeAssemblyOrDefault); }); } if (needsXml) { assembliesElement = new XElement("assemblies"); } var originalWorkingFolder = Directory.GetCurrentDirectory(); using (AssemblyHelper.SubscribeResolve()) { var clockTime = Stopwatch.StartNew(); if (parallelizeAssemblies.GetValueOrDefault()) { var tasks = project.Assemblies.Select(assembly => TaskRun(() => ExecuteAssembly( consoleLock, (XunitProjectAssembly2)assembly, needsXml, parallelizeTestCollections, maxThreadCount, diagnosticMessages, noColor, project.Filters, designTime, list, designTimeFullyQualifiedNames))); var results = Task.WhenAll(tasks).GetAwaiter().GetResult(); foreach (var assemblyElement in results.Where(result => result != null)) { assembliesElement.Add(assemblyElement); } } else { foreach (var assembly in project.Assemblies) { var assemblyElement = ExecuteAssembly( consoleLock, (XunitProjectAssembly2)assembly, needsXml, parallelizeTestCollections, maxThreadCount, diagnosticMessages, noColor, project.Filters, designTime, list, designTimeFullyQualifiedNames); if (assemblyElement != null) { assembliesElement.Add(assemblyElement); } } } SendTestCompletedIfNecessary(designTime, list); clockTime.Stop(); if (_completionMessages.Count > 0) { _reporterMessageHandler.OnMessage(new TestExecutionSummary(clockTime.Elapsed, _completionMessages.OrderBy(kvp => kvp.Key).ToList())); } } Directory.SetCurrentDirectory(originalWorkingFolder); foreach (var transformer in xmlTransformers) { transformer(assembliesElement); } return(_failed ? 1 : _completionMessages.Values.Sum(summary => summary.Failed)); }
public override bool Execute() { RemotingUtility.CleanUpRegisteredChannels(); XElement assembliesElement = null; var environment = $"{IntPtr.Size * 8}-bit .NET {Environment.Version}"; if (NeedsXml) assembliesElement = new XElement("assemblies"); switch (MaxParallelThreads) { case null: case "default": break; case "unlimited": maxThreadCount = -1; break; default: int threadValue; if (!int.TryParse(MaxParallelThreads, out threadValue) || threadValue < 1) { Log.LogError("MaxParallelThreads value '{0}' is invalid: must be 'default', 'unlimited', or a positive number", MaxParallelThreads); return false; } maxThreadCount = threadValue; break; } var originalWorkingFolder = Directory.GetCurrentDirectory(); using (AssemblyHelper.SubscribeResolve()) { var reporter = GetReporter(); if (reporter == null) return false; logger = new MSBuildLogger(Log); reporterMessageHandler = MessageSinkWithTypesAdapter.Wrap(reporter.CreateMessageHandler(logger)); if (!NoLogo) Log.LogMessage(MessageImportance.High, "xUnit.net MSBuild Runner ({0})", environment); var project = new XunitProject(); foreach (var assembly in Assemblies) { var assemblyFileName = assembly.GetMetadata("FullPath"); var configFileName = assembly.GetMetadata("ConfigFile"); if (configFileName != null && configFileName.Length == 0) configFileName = null; var projectAssembly = new XunitProjectAssembly { AssemblyFilename = assemblyFileName, ConfigFilename = configFileName }; if (shadowCopy.HasValue) projectAssembly.Configuration.ShadowCopy = shadowCopy; project.Add(projectAssembly); } if (WorkingFolder != null) Directory.SetCurrentDirectory(WorkingFolder); var clockTime = Stopwatch.StartNew(); if (!parallelizeAssemblies.HasValue) parallelizeAssemblies = project.All(assembly => assembly.Configuration.ParallelizeAssemblyOrDefault); if (parallelizeAssemblies.GetValueOrDefault()) { var tasks = project.Assemblies.Select(assembly => Task.Run(() => ExecuteAssembly(assembly))); var results = Task.WhenAll(tasks).GetAwaiter().GetResult(); foreach (var assemblyElement in results.Where(result => result != null)) assembliesElement.Add(assemblyElement); } else { foreach (var assembly in project.Assemblies) { var assemblyElement = ExecuteAssembly(assembly); if (assemblyElement != null) assembliesElement.Add(assemblyElement); } } clockTime.Stop(); if (assembliesElement != null) assembliesElement.Add(new XAttribute("timestamp", DateTime.Now.ToString(CultureInfo.InvariantCulture))); if (completionMessages.Count > 0) reporterMessageHandler.OnMessage(new TestExecutionSummary(clockTime.Elapsed, completionMessages.OrderBy(kvp => kvp.Key).ToList())); } Directory.SetCurrentDirectory(WorkingFolder ?? originalWorkingFolder); if (NeedsXml) { if (Xml != null) assembliesElement.Save(Xml.GetMetadata("FullPath")); if (XmlV1 != null) Transform("xUnit1.xslt", assembliesElement, XmlV1); if (Html != null) Transform("HTML.xslt", assembliesElement, Html); if (NUnit != null) Transform("NUnitXml.xslt", assembliesElement, NUnit); } // ExitCode is set to 1 for test failures and -1 for Exceptions. return ExitCode == 0 || (ExitCode == 1 && IgnoreFailures); }
public override bool Execute() { RemotingUtility.CleanUpRegisteredChannels(); if (TeamCity) { Log.LogError("The 'TeamCity' property is deprecated. Please set the 'Reporter' property to 'teamcity' instead."); return(false); } if (Verbose) { Log.LogError("The 'Verbose' property is deprecated. Please set the 'Reporter' property to 'verbose' instead."); return(false); } XElement assembliesElement = null; var environment = $"{IntPtr.Size * 8}-bit .NET {Environment.Version}"; if (NeedsXml) { assembliesElement = new XElement("assemblies"); } switch (MaxParallelThreads) { case null: case "default": break; case "unlimited": maxThreadCount = -1; break; default: int threadValue; if (!int.TryParse(MaxParallelThreads, out threadValue) || threadValue < 1) { Log.LogError("MaxParallelThreads value '{0}' is invalid: must be 'default', 'unlimited', or a positive number", MaxParallelThreads); return(false); } maxThreadCount = threadValue; break; } var originalWorkingFolder = Directory.GetCurrentDirectory(); using (AssemblyHelper.SubscribeResolve()) { var reporters = GetAvailableRunnerReporters(); var reporter = reporters.FirstOrDefault(r => r.IsEnvironmentallyEnabled); if (reporter == null && !string.IsNullOrWhiteSpace(Reporter)) { reporter = reporters.FirstOrDefault(r => string.Equals(r.RunnerSwitch, Reporter, StringComparison.OrdinalIgnoreCase)); if (reporter == null) { var switchableReporters = reporters.Where(r => !string.IsNullOrWhiteSpace(r.RunnerSwitch)).Select(r => r.RunnerSwitch.ToLowerInvariant()).OrderBy(x => x).ToList(); if (switchableReporters.Count == 0) { Log.LogError("Reporter value '{0}' is invalid. There are no available reporters.", Reporter); } else { Log.LogError("Reporter value '{0}' is invalid. Available reporters: {1}", Reporter, string.Join(", ", switchableReporters)); } return(false); } } if (reporter == null) { reporter = new DefaultRunnerReporter(); } logger = new MSBuildLogger(Log); reporterMessageHandler = reporter.CreateMessageHandler(logger); if (!NoLogo) { Log.LogMessage(MessageImportance.High, "xUnit.net MSBuild Runner ({0})", environment); } var project = new XunitProject(); foreach (var assembly in Assemblies) { var assemblyFileName = assembly.GetMetadata("FullPath"); var configFileName = assembly.GetMetadata("ConfigFile"); if (configFileName != null && configFileName.Length == 0) { configFileName = null; } project.Add(new XunitProjectAssembly { AssemblyFilename = assemblyFileName, ConfigFilename = configFileName, ShadowCopy = ShadowCopy }); } if (WorkingFolder != null) { Directory.SetCurrentDirectory(WorkingFolder); } var clockTime = Stopwatch.StartNew(); if (!parallelizeAssemblies.HasValue) { parallelizeAssemblies = project.All(assembly => assembly.Configuration.ParallelizeAssemblyOrDefault); } if (parallelizeAssemblies.GetValueOrDefault()) { var tasks = project.Assemblies.Select(assembly => Task.Run(() => ExecuteAssembly(assembly))); var results = Task.WhenAll(tasks).GetAwaiter().GetResult(); foreach (var assemblyElement in results.Where(result => result != null)) { assembliesElement.Add(assemblyElement); } } else { foreach (var assembly in project.Assemblies) { var assemblyElement = ExecuteAssembly(assembly); if (assemblyElement != null) { assembliesElement.Add(assemblyElement); } } } clockTime.Stop(); if (completionMessages.Count > 0) { reporterMessageHandler.OnMessage(new TestExecutionSummary(clockTime.Elapsed, completionMessages.OrderBy(kvp => kvp.Key).ToList())); } } Directory.SetCurrentDirectory(WorkingFolder ?? originalWorkingFolder); if (NeedsXml) { if (Xml != null) { assembliesElement.Save(Xml.GetMetadata("FullPath")); } if (XmlV1 != null) { Transform("xUnit1.xslt", assembliesElement, XmlV1); } if (Html != null) { Transform("HTML.xslt", assembliesElement, Html); } if (NUnit != null) { Transform("NUnitXml.xslt", assembliesElement, NUnit); } } return(ExitCode == 0); }
static int RunProject(XunitProject project, bool serialize, bool? parallelizeAssemblies, bool? parallelizeTestCollections, int? maxThreadCount, bool diagnosticMessages, bool noColor, bool noAppDomain, bool failSkips) { XElement assembliesElement = null; var clockTime = Stopwatch.StartNew(); var xmlTransformers = TransformFactory.GetXmlTransformers(project); var needsXml = xmlTransformers.Count > 0; var consoleLock = new object(); if (!parallelizeAssemblies.HasValue) parallelizeAssemblies = project.All(assembly => assembly.Configuration.ParallelizeAssemblyOrDefault); if (needsXml) assembliesElement = new XElement("assemblies"); var originalWorkingFolder = Directory.GetCurrentDirectory(); using (AssemblyHelper.SubscribeResolve()) { if (parallelizeAssemblies.GetValueOrDefault()) { var tasks = project.Assemblies.Select(assembly => Task.Run(() => ExecuteAssembly(consoleLock, assembly, serialize, needsXml, parallelizeTestCollections, maxThreadCount, diagnosticMessages, noColor, noAppDomain, failSkips, project.Filters))); var results = Task.WhenAll(tasks).GetAwaiter().GetResult(); foreach (var assemblyElement in results.Where(result => result != null)) assembliesElement.Add(assemblyElement); } else { foreach (var assembly in project.Assemblies) { var assemblyElement = ExecuteAssembly(consoleLock, assembly, serialize, needsXml, parallelizeTestCollections, maxThreadCount, diagnosticMessages, noColor, noAppDomain, failSkips, project.Filters); if (assemblyElement != null) assembliesElement.Add(assemblyElement); } } clockTime.Stop(); if (completionMessages.Count > 0) reporterMessageHandler.OnMessage(new TestExecutionSummary(clockTime.Elapsed, completionMessages.OrderBy(kvp => kvp.Key).ToList())); } Directory.SetCurrentDirectory(originalWorkingFolder); xmlTransformers.ForEach(transformer => transformer(assembliesElement)); return failed ? 1 : completionMessages.Values.Sum(summary => summary.Failed); }
static int RunProject(string defaultDirectory, XunitProject project, bool teamcity, bool appVeyor, bool showProgress, bool?parallelizeAssemblies, bool?parallelizeTestCollections, int?maxThreadCount) { XElement assembliesElement = null; var xmlTransformers = TransformFactory.GetXmlTransformers(project); var needsXml = xmlTransformers.Count > 0; var consoleLock = new object(); if (!parallelizeAssemblies.HasValue) { parallelizeAssemblies = project.All(assembly => assembly.Configuration.ParallelizeAssembly ?? false); } if (needsXml) { assembliesElement = new XElement("assemblies"); } var originalWorkingFolder = Directory.GetCurrentDirectory(); using (AssemblyHelper.SubscribeResolve()) { var clockTime = Stopwatch.StartNew(); if (parallelizeAssemblies.GetValueOrDefault()) { var tasks = project.Assemblies.Select(assembly => Task.Run(() => ExecuteAssembly(consoleLock, defaultDirectory, assembly, needsXml, teamcity, appVeyor, showProgress, parallelizeTestCollections, maxThreadCount, project.Filters))); var results = Task.WhenAll(tasks).GetAwaiter().GetResult(); foreach (var assemblyElement in results.Where(result => result != null)) { assembliesElement.Add(assemblyElement); } } else { foreach (var assembly in project.Assemblies) { var assemblyElement = ExecuteAssembly(consoleLock, defaultDirectory, assembly, needsXml, teamcity, appVeyor, showProgress, parallelizeTestCollections, maxThreadCount, project.Filters); if (assemblyElement != null) { assembliesElement.Add(assemblyElement); } } } clockTime.Stop(); if (completionMessages.Count > 0) { Console.ForegroundColor = ConsoleColor.White; Console.WriteLine(); Console.WriteLine("=== TEST EXECUTION SUMMARY ==="); Console.ForegroundColor = ConsoleColor.Gray; var totalTestsRun = completionMessages.Values.Sum(summary => summary.Total); var totalTestsFailed = completionMessages.Values.Sum(summary => summary.Failed); var totalTestsSkipped = completionMessages.Values.Sum(summary => summary.Skipped); var totalTime = completionMessages.Values.Sum(summary => summary.Time).ToString("0.000s"); var totalErrors = completionMessages.Values.Sum(summary => summary.Errors); var longestAssemblyName = completionMessages.Keys.Max(key => key.Length); var longestTotal = totalTestsRun.ToString().Length; var longestFailed = totalTestsFailed.ToString().Length; var longestSkipped = totalTestsSkipped.ToString().Length; var longestTime = totalTime.Length; var longestErrors = totalErrors.ToString().Length; foreach (var message in completionMessages.OrderBy(m => m.Key)) { Console.WriteLine(" {0} Total: {1}, Errors: {2}, Failed: {3}, Skipped: {4}, Time: {5}", message.Key.PadRight(longestAssemblyName), message.Value.Total.ToString().PadLeft(longestTotal), message.Value.Errors.ToString().PadLeft(longestErrors), message.Value.Failed.ToString().PadLeft(longestFailed), message.Value.Skipped.ToString().PadLeft(longestSkipped), message.Value.Time.ToString("0.000s").PadLeft(longestTime)); } if (completionMessages.Count > 1) { Console.WriteLine(" {0} {1} {2} {3} {4} {5}" + Environment.NewLine + " {6} {7} {8} {9} {10} {11} ({12})", " ".PadRight(longestAssemblyName), "-".PadRight(longestTotal, '-'), "-".PadRight(longestErrors, '-'), "-".PadRight(longestFailed, '-'), "-".PadRight(longestSkipped, '-'), "-".PadRight(longestTime, '-'), "GRAND TOTAL:".PadLeft(longestAssemblyName), totalTestsRun, totalErrors, totalTestsFailed, totalTestsSkipped, totalTime, clockTime.Elapsed.TotalSeconds.ToString("0.000s")); } } } Directory.SetCurrentDirectory(originalWorkingFolder); xmlTransformers.ForEach(transformer => transformer(assembliesElement)); return(failed ? 1 : completionMessages.Values.Sum(summary => summary.Failed)); }
public static List<Action<XElement>> GetXmlTransformers(XunitProject project) { return project.Output.Select(output => new Action<XElement>(xml => instance.availableTransforms[output.Key].OutputHandler(xml, output.Value))).ToList(); }
static int RunProject(string defaultDirectory, XunitProject project, bool teamcity, bool silent, bool parallelizeAssemblies, bool parallelizeTestCollections, int maxThreadCount) { XElement assembliesElement = null; var xmlTransformers = TransformFactory.GetXmlTransformers(project); var needsXml = xmlTransformers.Count > 0; var consoleLock = new object(); if (needsXml) assembliesElement = new XElement("assemblies"); string originalWorkingFolder = Directory.GetCurrentDirectory(); using (AssemblyHelper.SubscribeResolve()) { if (parallelizeAssemblies) { var tasks = project.Assemblies.Select(assembly => Task.Run(() => ExecuteAssembly(consoleLock, defaultDirectory, assembly, needsXml, teamcity, silent, parallelizeTestCollections, maxThreadCount))); var results = Task.WhenAll(tasks).GetAwaiter().GetResult(); foreach (var assemblyElement in results.Where(result => result != null)) assembliesElement.Add(assemblyElement); } else { foreach (var assembly in project.Assemblies) { var assemblyElement = ExecuteAssembly(consoleLock, defaultDirectory, assembly, needsXml, teamcity, silent, parallelizeTestCollections, maxThreadCount); if (assemblyElement != null) assembliesElement.Add(assemblyElement); } } if (completionMessages.Count > 0) { Console.WriteLine(); Console.WriteLine("=== TEST EXECUTION SUMMARY ==="); int longestAssemblyName = completionMessages.Keys.Max(key => key.Length); int longestTotal = completionMessages.Values.Max(summary => summary.Total.ToString().Length); int longestFailed = completionMessages.Values.Max(summary => summary.Failed.ToString().Length); int longestSkipped = completionMessages.Values.Max(summary => summary.Skipped.ToString().Length); int longestTime = completionMessages.Values.Max(summary => summary.Time.ToString("0.000s").Length); foreach (var message in completionMessages.OrderBy(m => m.Key)) Console.WriteLine(" {0} Total: {1}, Failed: {2}, Skipped: {3}, Time: {4}", message.Key.PadRight(longestAssemblyName), message.Value.Total.ToString().PadLeft(longestTotal), message.Value.Failed.ToString().PadLeft(longestFailed), message.Value.Skipped.ToString().PadLeft(longestSkipped), message.Value.Time.ToString("0.000s").PadLeft(longestTime)); } } Directory.SetCurrentDirectory(originalWorkingFolder); xmlTransformers.ForEach(transformer => transformer(assembliesElement)); return failed ? 1 : completionMessages.Values.Sum(summary => summary.Failed); }
void menuProjectClose_Click(object sender, EventArgs e) { if (project.IsDirty) if (MessageBox.Show("Are you sure you want to close this project? You have unsaved changes.", windowTitle, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) != DialogResult.OK) return; UnloadAssemblies(listAssemblies.Items); project = new XunitProject(); UpdateRunState(); }
static XunitProject GetSingleAssemblyProject(Dictionary<string, string> transforms, string assemblyFile, string configFile, bool noShadow) { XunitProjectAssembly assembly = new XunitProjectAssembly { AssemblyFilename = assemblyFile, ConfigFilename = configFile, ShadowCopy = !noShadow }; foreach (var transform in transforms) assembly.Output.Add(transform.Key, transform.Value); XunitProject project = new XunitProject(); project.AddAssembly(assembly); return project; }
static int RunProject(string defaultDirectory, XunitProject project, bool teamcity, bool appVeyor, bool silent, bool parallelizeAssemblies, bool parallelizeTestCollections, int maxThreadCount) { XElement assembliesElement = null; var xmlTransformers = TransformFactory.GetXmlTransformers(project); var needsXml = xmlTransformers.Count > 0; var consoleLock = new object(); if (needsXml) assembliesElement = new XElement("assemblies"); var originalWorkingFolder = Directory.GetCurrentDirectory(); using (AssemblyHelper.SubscribeResolve()) { if (parallelizeAssemblies) { var tasks = project.Assemblies.Select(assembly => Task.Run(() => ExecuteAssembly(consoleLock, defaultDirectory, assembly, needsXml, teamcity, appVeyor, silent, parallelizeTestCollections, maxThreadCount, project.Filters))); var results = Task.WhenAll(tasks).GetAwaiter().GetResult(); foreach (var assemblyElement in results.Where(result => result != null)) assembliesElement.Add(assemblyElement); } else { foreach (var assembly in project.Assemblies) { var assemblyElement = ExecuteAssembly(consoleLock, defaultDirectory, assembly, needsXml, teamcity, appVeyor, silent, parallelizeTestCollections, maxThreadCount, project.Filters); if (assemblyElement != null) assembliesElement.Add(assemblyElement); } } if (completionMessages.Count > 0) { Console.ForegroundColor = ConsoleColor.White; Console.WriteLine(); Console.WriteLine("=== TEST EXECUTION SUMMARY ==="); Console.ForegroundColor = ConsoleColor.Gray; var totalTestsRun = completionMessages.Values.Sum(summary => summary.Total); var totalTestsFailed = completionMessages.Values.Sum(summary => summary.Failed); var totalTestsSkipped = completionMessages.Values.Sum(summary => summary.Skipped); var totalTime = completionMessages.Values.Sum(summary => summary.Time).ToString("0.000s"); var totalErrors = completionMessages.Values.Sum(summary => summary.Errors); var longestAssemblyName = completionMessages.Keys.Max(key => key.Length); var longestTotal = totalTestsRun.ToString().Length; var longestFailed = totalTestsFailed.ToString().Length; var longestSkipped = totalTestsSkipped.ToString().Length; var longestTime = totalTime.Length; var longestErrors = totalErrors.ToString().Length; foreach (var message in completionMessages.OrderBy(m => m.Key)) Console.WriteLine(" {0} Total: {1}, Failed: {2}, Skipped: {3}, Time: {4}, Errors: {5}", message.Key.PadRight(longestAssemblyName), message.Value.Total.ToString().PadLeft(longestTotal), message.Value.Failed.ToString().PadLeft(longestFailed), message.Value.Skipped.ToString().PadLeft(longestSkipped), message.Value.Time.ToString("0.000s").PadLeft(longestTime), message.Value.Errors.ToString().PadLeft(longestErrors)); if (completionMessages.Count > 1) Console.WriteLine(" {0} {1} {2} {3} {4} {5}" + Environment.NewLine + " {6} {7} {8} {9} {10} {11}", " ".PadRight(longestAssemblyName), "-".PadRight(longestTotal, '-'), "-".PadRight(longestFailed, '-'), "-".PadRight(longestSkipped, '-'), "-".PadRight(longestTime, '-'), "-".PadRight(longestErrors, '-'), "GRAND TOTAL:".PadLeft(longestAssemblyName), totalTestsRun, totalTestsFailed, totalTestsSkipped, totalTime, totalErrors); } } Directory.SetCurrentDirectory(originalWorkingFolder); xmlTransformers.ForEach(transformer => transformer(assembliesElement)); return failed ? 1 : completionMessages.Values.Sum(summary => summary.Failed); }
static int RunProject(XunitProject project, bool teamcity, bool silent, bool parallel) { XElement assembliesElement = null; var needsXml = project.Output.Count > 0; if (needsXml) assembliesElement = new XElement("assemblies"); string originalWorkingFolder = Directory.GetCurrentDirectory(); using (AssemblyHelper.SubscribeResolve()) { if (parallel) { var tasks = project.Assemblies.Select(assembly => Task.Run(() => ExecuteAssembly(assembly, needsXml, teamcity, silent))); var results = Task.WhenAll(tasks).GetAwaiter().GetResult(); foreach (var assemblyElement in results.Where(result => result != null)) assembliesElement.Add(assemblyElement); } else { foreach (var assembly in project.Assemblies) { var assemblyElement = ExecuteAssembly(assembly, needsXml, teamcity, silent); if (assemblyElement != null) assembliesElement.Add(assemblyElement); } } if (completionMessages.Count > 0) { Console.WriteLine("=== TEST EXECUTION SUMMARY ==="); int longestAssemblyName = completionMessages.Keys.Max(key => key.Length); int longestTotal = completionMessages.Values.Max(summary => summary.Total.ToString().Length); int longestFailed = completionMessages.Values.Max(summary => summary.Failed.ToString().Length); int longestSkipped = completionMessages.Values.Max(summary => summary.Skipped.ToString().Length); foreach (var message in completionMessages.OrderBy(m => m.Key)) Console.WriteLine(" {0} Total: {1}, Failed: {2}, Skipped: {3}", message.Key.PadRight(longestAssemblyName), message.Value.Total.ToString().PadLeft(longestTotal), message.Value.Failed.ToString().PadLeft(longestFailed), message.Value.Skipped.ToString().PadLeft(longestSkipped)); } } Directory.SetCurrentDirectory(originalWorkingFolder); if (needsXml) { //if (Xml != null) // assembliesElement.Save(Xml.GetMetadata("FullPath")); //if (XmlV1 != null) // Transform("xUnit1.xslt", assembliesElement, XmlV1); //if (Html != null) // Transform("HTML.xslt", assembliesElement, Html); } return completionMessages.Values.Sum(summary => summary.Failed); }