ManualResetEvent RunTestsInAssemblyAsync(IDiscoveryContext discoveryContext, IFrameworkHandle frameworkHandle, List <IDisposable> toDispose, string assemblyFileName, IEnumerable <TestCase> testCases, XunitVisualStudioSettings settings, Stopwatch stopwatch) { var @event = new ManualResetEvent(initialState: false); Action handler = () => { try { RunTestsInAssembly(discoveryContext, frameworkHandle, toDispose, assemblyFileName, testCases, settings, stopwatch); } finally { @event.Set(); } }; #if WINDOWS_PHONE_APP Windows.System.Threading.ThreadPool.RunAsync(_ => handler()); #else ThreadPool.QueueUserWorkItem(_ => handler()); #endif return(@event); }
public VsDiscoveryVisitor(string source, ITestFrameworkDiscoverer discoverer, IMessageLogger logger, ITestCaseDiscoverySink discoverySink, Func <bool> cancelThunk) { this.source = source; this.discoverer = discoverer; this.logger = logger; this.discoverySink = discoverySink; this.cancelThunk = cancelThunk; settings = SettingsProvider.Load(); }
void RunTestsInAssembly(IDiscoveryContext discoveryContext, IFrameworkHandle frameworkHandle, List <IDisposable> toDispose, string assemblyFileName, IEnumerable <TestCase> testCases, XunitVisualStudioSettings settings, Stopwatch stopwatch) { if (cancelled) { return; } if (settings.MessageDisplay == MessageDisplay.Diagnostic) { lock (stopwatch) frameworkHandle.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Execution starting: {1}", stopwatch.Elapsed, Path.GetFileName(assemblyFileName))); } #if WIN8_STORE // For store apps, the files are copied to the AppX dir, we need to load it from there assemblyFileName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Path.GetFileName(assemblyFileName)); #elif WINDOWS_PHONE_APP // For WPA Apps, use the package location assemblyFileName = Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path, Path.GetFileName(assemblyFileName)); #endif var controller = new XunitFrontController(assemblyFileName, configFileName: null, shadowCopy: true); lock (toDispose) toDispose.Add(controller); var xunitTestCases = testCases.ToDictionary(tc => controller.Deserialize(tc.GetPropertyValue <string>(SerializedTestCaseProperty, null))); using (var executionVisitor = new VsExecutionVisitor(discoveryContext, frameworkHandle, xunitTestCases, () => cancelled)) { var executionOptions = new XunitExecutionOptions { DisableParallelization = !settings.ParallelizeTestCollections, MaxParallelThreads = settings.MaxParallelThreads }; controller.RunTests(xunitTestCases.Keys.ToList(), executionVisitor, executionOptions); executionVisitor.Finished.WaitOne(); } if (settings.MessageDisplay == MessageDisplay.Diagnostic) { lock (stopwatch) frameworkHandle.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Execution finished: {1}", stopwatch.Elapsed, Path.GetFileName(assemblyFileName))); } }
public VsExecutionVisitor(IDiscoveryContext discoveryContext, ITestExecutionRecorder recorder, Dictionary <ITestCase, TestCase> testCases, Func <bool> cancelledThunk) { this.recorder = recorder; this.testCases = testCases; this.cancelledThunk = cancelledThunk; settings = SettingsProvider.Load(); var settingsProvider = discoveryContext.RunSettings.GetSettings(XunitTestRunSettings.SettingsName) as XunitTestRunSettingsProvider; if (settingsProvider != null && settingsProvider.Settings != null) { settings.Merge(settingsProvider.Settings); } }
public VsDiscoveryVisitor(string source, ITestFrameworkDiscoverer discoverer, IMessageLogger logger, IDiscoveryContext discoveryContext, ITestCaseDiscoverySink discoverySink, Func <bool> cancelThunk) { this.source = source; this.discoverer = discoverer; this.logger = logger; this.discoverySink = discoverySink; this.cancelThunk = cancelThunk; settings = SettingsProvider.Load(); var settingsProvider = discoveryContext.RunSettings.GetSettings(XunitTestRunSettings.SettingsName) as XunitTestRunSettingsProvider; if (settingsProvider != null && settingsProvider.Settings != null) { settings.Merge(settingsProvider.Settings); } }
void RunTestsInAssembly(IDiscoveryContext discoveryContext, IFrameworkHandle frameworkHandle, List <IDisposable> toDispose, string assemblyFileName, IEnumerable <TestCase> testCases, XunitVisualStudioSettings settings, Stopwatch stopwatch) { if (cancelled) { return; } if (settings.MessageDisplay == MessageDisplay.Diagnostic) { lock (stopwatch) frameworkHandle.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Execution starting: {1}", stopwatch.Elapsed, Path.GetFileName(assemblyFileName))); } var controller = new XunitFrontController(assemblyFileName, configFileName: null, shadowCopy: true); lock (toDispose) toDispose.Add(controller); var xunitTestCases = testCases.ToDictionary(tc => controller.Deserialize(tc.GetPropertyValue <string>(SerializedTestCaseProperty, null))); using (var executionVisitor = new VsExecutionVisitor(discoveryContext, frameworkHandle, xunitTestCases, () => cancelled)) { var executionOptions = new XunitExecutionOptions { DisableParallelization = !settings.ParallelizeTestCollections, MaxParallelThreads = settings.MaxParallelThreads }; controller.RunTests(xunitTestCases.Keys.ToList(), executionVisitor, executionOptions); executionVisitor.Finished.WaitOne(); } if (settings.MessageDisplay == MessageDisplay.Diagnostic) { lock (stopwatch) frameworkHandle.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Execution finished: {1}", stopwatch.Elapsed, Path.GetFileName(assemblyFileName))); } }
ManualResetEvent RunTestsInAssemblyAsync(IFrameworkHandle frameworkHandle, List <IDisposable> toDispose, string assemblyFileName, IEnumerable <TestCase> testCases, XunitVisualStudioSettings settings, Stopwatch stopwatch) { var @event = new ManualResetEvent(initialState: false); ThreadPool.QueueUserWorkItem(_ => { try { RunTestsInAssembly(frameworkHandle, toDispose, assemblyFileName, testCases, settings, stopwatch); } finally { @event.Set(); } }); return(@event); }
public static TestCase CreateVsTestCase(string source, ITestFrameworkDiscoverer discoverer, ITestCase xunitTestCase, XunitVisualStudioSettings settings, bool forceUniqueNames) { var serializedTestCase = discoverer.Serialize(xunitTestCase); var fqTestMethodName = String.Format("{0}.{1}", xunitTestCase.Class.Name, xunitTestCase.Method.Name); var displayName = settings.GetDisplayName(xunitTestCase.DisplayName, xunitTestCase.Method.Name, fqTestMethodName); var uniqueName = forceUniqueNames ? String.Format("{0} ({1})", fqTestMethodName, xunitTestCase.UniqueID) : fqTestMethodName; var result = new TestCase(uniqueName, uri, source) { DisplayName = Escape(displayName) }; result.SetPropertyValue(VsTestRunner.SerializedTestCaseProperty, serializedTestCase); if (addTraitThunk != null) { foreach (var key in xunitTestCase.Traits.Keys) { foreach (var value in xunitTestCase.Traits[key]) { addTraitThunk(result, key, value); } } } result.CodeFilePath = xunitTestCase.SourceInformation.FileName; result.LineNumber = xunitTestCase.SourceInformation.LineNumber.GetValueOrDefault(); return(result); }
static string GetDisplayName(string displayName, string shortMethodName, string fullyQualifiedMethodName, XunitVisualStudioSettings settings) { if (settings.NameDisplay == NameDisplay.Full) { return(displayName); } if (displayName == fullyQualifiedMethodName || displayName.StartsWith(fullyQualifiedMethodName + "(")) { return(shortMethodName + displayName.Substring(fullyQualifiedMethodName.Length)); } return(displayName); }
void DiscoverTests <TVisitor>(IEnumerable <string> sources, IMessageLogger logger, XunitVisualStudioSettings settings, Func <string, ITestFrameworkDiscoverer, TVisitor> visitorFactory, Action <string, ITestFrameworkDiscoverer, TVisitor> visitComplete = null, Stopwatch stopwatch = null) where TVisitor : IVsDiscoveryVisitor { if (stopwatch == null) { stopwatch = Stopwatch.StartNew(); } try { RemotingUtility.CleanUpRegisteredChannels(); if (settings.MessageDisplay == MessageDisplay.Diagnostic) { logger.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Discovery started", stopwatch.Elapsed)); } using (AssemblyHelper.SubscribeResolve()) { foreach (string assemblyFileName in sources) { var fileName = Path.GetFileName(assemblyFileName); try { if (cancelled) { break; } if (!IsXunitTestAssembly(assemblyFileName)) { if (settings.MessageDisplay == MessageDisplay.Diagnostic) { logger.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Skipping: {1} (no reference to xUnit.net)", stopwatch.Elapsed, fileName)); } } else { using (var framework = new XunitFrontController(assemblyFileName, configFileName: null, shadowCopy: true)) using (var visitor = visitorFactory(assemblyFileName, framework)) { var targetFramework = framework.TargetFramework; if (targetFramework.StartsWith("MonoTouch", StringComparison.OrdinalIgnoreCase) || targetFramework.StartsWith("MonoAndroid", StringComparison.OrdinalIgnoreCase)) { if (settings.MessageDisplay == MessageDisplay.Diagnostic) { logger.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Skipping: {1} (unsupported target framework '{2}')", stopwatch.Elapsed, fileName, targetFramework)); } } else { if (settings.MessageDisplay == MessageDisplay.Diagnostic) { logger.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Discovery starting: {1}", stopwatch.Elapsed, fileName)); } framework.Find(includeSourceInformation: true, messageSink: visitor, options: new TestFrameworkOptions()); var totalTests = visitor.Finish(); if (visitComplete != null) { visitComplete(assemblyFileName, framework, visitor); } if (settings.MessageDisplay == MessageDisplay.Diagnostic) { logger.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Discovery finished: {1} ({2} tests)", stopwatch.Elapsed, fileName, totalTests)); } } } } } catch (Exception e) { var ex = e.Unwrap(); var fileNotFound = ex as FileNotFoundException; var fileLoad = ex as FileLoadException; if (fileNotFound != null) { logger.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Skipping: {1} (could not find dependent assembly '{2}')", stopwatch.Elapsed, fileName, Path.GetFileNameWithoutExtension(fileNotFound.FileName))); } else if (fileLoad != null) { logger.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Skipping: {1} (could not find dependent assembly '{2}')", stopwatch.Elapsed, fileName, Path.GetFileNameWithoutExtension(fileLoad.FileName))); } else { logger.SendMessage(TestMessageLevel.Error, String.Format("[xUnit.net {0}] Exception discovering tests from {1}: {2}", stopwatch.Elapsed, fileName, ex)); } } } } } catch (Exception e) { logger.SendMessage(TestMessageLevel.Error, String.Format("[xUnit.net {0}] Exception discovering tests: {1}", stopwatch.Elapsed, e.Unwrap())); } stopwatch.Stop(); if (settings.MessageDisplay == MessageDisplay.Diagnostic) { logger.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Discovery complete", stopwatch.Elapsed)); } }
IEnumerable <IGrouping <string, TestCase> > GetTests(IEnumerable <string> sources, IMessageLogger logger, XunitVisualStudioSettings settings, Stopwatch stopwatch) { var result = new List <IGrouping <string, TestCase> >(); DiscoverTests( sources, logger, settings, (source, discoverer) => new VsExecutionDiscoveryVisitor(), (source, discoverer, visitor) => result.Add( new Grouping <string, TestCase>( source, visitor.TestCases .GroupBy(tc => String.Format("{0}.{1}", tc.Class.Name, tc.Method.Name)) .SelectMany(group => group.Select(testCase => VsDiscoveryVisitor.CreateVsTestCase(source, discoverer, testCase, settings, forceUniqueNames: group.Count() > 1))) .ToList() ) ), stopwatch ); return(result); }
IEnumerable <IGrouping <string, TestCase> > GetTests(IEnumerable <string> sources, IMessageLogger logger, XunitVisualStudioSettings settings, Stopwatch stopwatch) { var result = new List <IGrouping <string, TestCase> >(); RemotingUtility.CleanUpRegisteredChannels(); using (AssemblyHelper.SubscribeResolve()) { if (settings.MessageDisplay == MessageDisplay.Diagnostic) { logger.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Discovery started", stopwatch.Elapsed)); } foreach (string assemblyFileName in sources) { var fileName = Path.GetFileName(assemblyFileName); try { if (cancelled) { break; } if (!IsXunitTestAssembly(assemblyFileName)) { if (settings.MessageDisplay == MessageDisplay.Diagnostic) { logger.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Skipping: {1}", stopwatch.Elapsed, fileName)); } } else { if (settings.MessageDisplay == MessageDisplay.Diagnostic) { logger.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Discovery starting: {1}", stopwatch.Elapsed, fileName)); } using (var framework = new XunitFrontController(assemblyFileName, configFileName: null, shadowCopy: true)) using (var sink = new TestDiscoveryVisitor()) { framework.Find(includeSourceInformation: true, messageSink: sink, options: new TestFrameworkOptions()); sink.Finished.WaitOne(); result.Add( new Grouping <string, TestCase>( assemblyFileName, sink.TestCases .GroupBy(tc => String.Format("{0}.{1}", tc.Class.Name, tc.Method.Name)) .SelectMany(group => group.Select(testCase => VsDiscoveryVisitor.CreateVsTestCase(assemblyFileName, framework, testCase, settings, forceUniqueNames: group.Count() > 1))) .ToList() ) ); if (settings.MessageDisplay != MessageDisplay.None) { logger.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Discovery finished: {1} ({2} tests)", stopwatch.Elapsed, Path.GetFileName(assemblyFileName), sink.TestCases.Count)); } } } } catch (Exception e) { logger.SendMessage(TestMessageLevel.Error, String.Format("[xUnit.net {0}] Exception discovering tests from {1}: {2}", stopwatch.Elapsed, assemblyFileName, e)); } } if (settings.MessageDisplay == MessageDisplay.Diagnostic) { logger.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Discovery complete", stopwatch.Elapsed)); } return(result); } }
IEnumerable <IGrouping <string, TestCase> > GetTests(IEnumerable <string> sources, IMessageLogger logger, XunitVisualStudioSettings settings, Stopwatch stopwatch) { var sourceSinks = new List <SourceSink <TestDiscoveryVisitor> >(); var result = new List <IGrouping <string, TestCase> >(); try { if (settings.MessageDisplay == MessageDisplay.Diagnostic) { lock (stopwatch) logger.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Discovery started", stopwatch.Elapsed)); } foreach (string assemblyFileName in sources) { try { if (cancelled) { break; } if (!IsXunitTestAssembly(assemblyFileName)) { if (settings.MessageDisplay == MessageDisplay.Diagnostic) { lock (stopwatch) logger.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Skipping: {1}", stopwatch.Elapsed, Path.GetFileName(assemblyFileName))); } } else { if (settings.MessageDisplay == MessageDisplay.Diagnostic) { lock (stopwatch) logger.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Discovery starting: {1}", stopwatch.Elapsed, Path.GetFileName(assemblyFileName))); } var framework = new XunitFrontController(assemblyFileName, configFileName: null, shadowCopy: true); var sink = new TestDiscoveryVisitor(); sourceSinks.Add(new SourceSink <TestDiscoveryVisitor> { Framework = framework, Sink = sink, AssemblyFileName = assemblyFileName }); framework.Find(includeSourceInformation: true, messageSink: sink); } } catch (Exception e) { lock (stopwatch) logger.SendMessage(TestMessageLevel.Error, String.Format("[xUnit.net {0}] Exception discovering tests from {1}: {2}", stopwatch.Elapsed, assemblyFileName, e)); } } var toFinish = new List <SourceSink <TestDiscoveryVisitor> >(sourceSinks); while (toFinish.Count > 0) { var finishedIdx = WaitHandle.WaitAny(sourceSinks.Select(sink => sink.Sink.Finished).ToArray()); var sourceSink = toFinish[finishedIdx]; result.Add( new Grouping <string, TestCase>( sourceSink.AssemblyFileName, sourceSink.Sink.TestCases .GroupBy(tc => String.Format("{0}.{1}", tc.Class.Name, tc.Method.Name)) .SelectMany(group => group.Select(testCase => VsDiscoveryVisitor.CreateVsTestCase(sourceSink.AssemblyFileName, sourceSink.Framework, testCase, settings, forceUniqueNames: group.Count() > 1))) .ToList() ) ); if (settings.MessageDisplay != MessageDisplay.None) { lock (stopwatch) logger.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Discovery finished: {1} ({2} tests)", stopwatch.Elapsed, Path.GetFileName(sourceSink.AssemblyFileName), sourceSink.Sink.TestCases.Count)); } toFinish.RemoveAt(finishedIdx); } } finally { foreach (var sourceSink in sourceSinks) { sourceSink.Sink.Dispose(); sourceSink.Framework.Dispose(); } } if (settings.MessageDisplay == MessageDisplay.Diagnostic) { lock (stopwatch) logger.SendMessage(TestMessageLevel.Informational, String.Format("[xUnit.net {0}] Discovery complete", stopwatch.Elapsed)); } return(result); }
IEnumerable <IGrouping <string, TestCase> > GetTests(IEnumerable <string> sources, IMessageLogger logger, XunitVisualStudioSettings settings, Stopwatch stopwatch) { #if WIN8_STORE // For store apps, the files are copied to the AppX dir, we need to load it from there sources = sources.Select(s => Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Path.GetFileName(s))); #elif WINDOWS_PHONE_APP sources = sources.Select(s => Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path, Path.GetFileName(s)));; #endif var result = new List <IGrouping <string, TestCase> >(); DiscoverTests( sources, logger, settings, (source, discoverer) => new VsExecutionDiscoveryVisitor(), (source, discoverer, visitor) => result.Add( new Grouping <string, TestCase>( source, visitor.TestCases .GroupBy(tc => String.Format("{0}.{1}", tc.TestMethod.TestClass.Class.Name, tc.TestMethod.Method.Name)) .SelectMany(group => group.Select(testCase => VsDiscoveryVisitor.CreateVsTestCase(source, discoverer, testCase, settings, forceUniqueNames: group.Count() > 1))) .ToList() ) ), stopwatch ); return(result); }