/// <inheritdoc/> protected void SetTestCaseOrderer(IReflectionTypeInfo Class) { var ordererAttribute = Class.GetCustomAttributes(typeof(TestCaseOrdererAttribute)).SingleOrDefault(); if (ordererAttribute != null) { try { var testCaseOrderer = ExtensibilityPointFactory.GetTestCaseOrderer(diagnosticMessageSink, ordererAttribute); if (testCaseOrderer != null) { TestCaseOrderer = testCaseOrderer; } else { var args = ordererAttribute.GetConstructorArguments().Cast <string>().ToList(); diagnosticMessageSink.OnMessage(new DiagnosticMessage($"Could not find type '{args[0]}' in {args[1]} for class-level test case orderer on test class '{Class.Name}'")); } } catch (Exception ex) { var innerEx = ex.InnerException ?? ex; //.Unwrap(); var args = ordererAttribute.GetConstructorArguments().Cast <string>().ToList(); diagnosticMessageSink.OnMessage(new DiagnosticMessage($"Class-level test case orderer '{args[0]}' for test class '{Class.Name}' threw '{innerEx.GetType().FullName}' " + $"during construction: {innerEx.Message}{Environment.NewLine}{innerEx.StackTrace}")); } } }
private static async Task RunTestClassAsync(IMessageBus messageBus, ITestCollection collection, Dictionary<Type, object> collectionFixtureMappings, IReflectionTypeInfo testClass, IEnumerable<XunitTestCase> testCases, ITestCaseOrderer orderer, RunSummary classSummary, ExceptionAggregator aggregator, CancellationTokenSource cancellationTokenSource) { var testClassType = testClass.Type; var fixtureMappings = new Dictionary<Type, object>(); var constructorArguments = new List<object>(); var ordererAttribute = testClass.GetCustomAttributes(typeof(TestCaseOrdererAttribute)).SingleOrDefault(); if (ordererAttribute != null) orderer = GetTestCaseOrderer(ordererAttribute); if (testClassType.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ICollectionFixture<>))) aggregator.Add(new TestClassException("A test class may not be decorated with ICollectionFixture<> (decorate the test collection class instead).")); foreach (var interfaceType in testClassType.GetInterfaces().Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IClassFixture<>))) CreateFixture(interfaceType, aggregator, fixtureMappings); if (collection.CollectionDefinition != null) { var declarationType = ((IReflectionTypeInfo)collection.CollectionDefinition).Type; foreach (var interfaceType in declarationType.GetInterfaces().Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IClassFixture<>))) CreateFixture(interfaceType, aggregator, fixtureMappings); } var isStaticClass = testClassType.IsAbstract && testClassType.IsSealed; if (!isStaticClass) { var ctors = testClassType.GetConstructors(); if (ctors.Length != 1) { aggregator.Add(new TestClassException("A test class may only define a single public constructor.")); } else { var ctor = ctors.Single(); var unusedArguments = new List<string>(); foreach (var paramInfo in ctor.GetParameters()) { object fixture; if (fixtureMappings.TryGetValue(paramInfo.ParameterType, out fixture) || collectionFixtureMappings.TryGetValue(paramInfo.ParameterType, out fixture)) constructorArguments.Add(fixture); else unusedArguments.Add(String.Format("{0} {1}", paramInfo.ParameterType.Name, paramInfo.Name)); } if (unusedArguments.Count > 0) aggregator.Add(new TestClassException("The following constructor arguments did not have matching fixture data: " + String.Join(", ", unusedArguments))); } } var orderedTestCases = orderer.OrderTestCases(testCases); var methodGroups = orderedTestCases.GroupBy(tc => tc.Method); foreach (var method in methodGroups) { if (!messageBus.QueueMessage(new TestMethodStarting(collection, testClass.Name, method.Key.Name))) cancellationTokenSource.Cancel(); else await RunTestMethodAsync(messageBus, constructorArguments.ToArray(), method, classSummary, aggregator, cancellationTokenSource); if (!messageBus.QueueMessage(new TestMethodFinished(collection, testClass.Name, method.Key.Name))) cancellationTokenSource.Cancel(); if (cancellationTokenSource.IsCancellationRequested) break; } foreach (var fixture in fixtureMappings.Values.OfType<IDisposable>()) { try { fixture.Dispose(); } catch (Exception ex) { if (!messageBus.QueueMessage(new ErrorMessage(ex.Unwrap()))) cancellationTokenSource.Cancel(); } } }
private static void RunTestClass(IMessageBus messageBus, ITestCollection collection, Dictionary <Type, object> collectionFixtureMappings, IReflectionTypeInfo testClass, IEnumerable <XunitTestCase> testCases, ITestCaseOrderer orderer, RunSummary classSummary, ExceptionAggregator aggregator, CancellationTokenSource cancellationTokenSource) { var testClassType = testClass.Type; var fixtureMappings = new Dictionary <Type, object>(); var constructorArguments = new List <object>(); var ordererAttribute = testClass.GetCustomAttributes(typeof(TestCaseOrdererAttribute)).SingleOrDefault(); if (ordererAttribute != null) { orderer = GetTestCaseOrderer(ordererAttribute); } if (testClassType.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ICollectionFixture <>))) { aggregator.Add(new TestClassException("A test class may not be decorated with ICollectionFixture<> (decorate the test collection class instead).")); } foreach (var interfaceType in testClassType.GetInterfaces().Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IClassFixture <>))) { CreateFixture(interfaceType, aggregator, fixtureMappings); } if (collection.CollectionDefinition != null) { var declarationType = ((IReflectionTypeInfo)collection.CollectionDefinition).Type; foreach (var interfaceType in declarationType.GetInterfaces().Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IClassFixture <>))) { CreateFixture(interfaceType, aggregator, fixtureMappings); } } var isStaticClass = testClassType.IsAbstract && testClassType.IsSealed; if (!isStaticClass) { var ctors = testClassType.GetConstructors(); if (ctors.Length != 1) { aggregator.Add(new TestClassException("A test class may only define a single public constructor.")); } else { var ctor = ctors.Single(); var unusedArguments = new List <string>(); foreach (var paramInfo in ctor.GetParameters()) { object fixture; if (fixtureMappings.TryGetValue(paramInfo.ParameterType, out fixture) || collectionFixtureMappings.TryGetValue(paramInfo.ParameterType, out fixture)) { constructorArguments.Add(fixture); } else { unusedArguments.Add(String.Format("{0} {1}", paramInfo.ParameterType.Name, paramInfo.Name)); } } if (unusedArguments.Count > 0) { aggregator.Add(new TestClassException("The following constructor arguments did not have matching fixture data: " + String.Join(", ", unusedArguments))); } } } var orderedTestCases = orderer.OrderTestCases(testCases); var methodGroups = orderedTestCases.GroupBy(tc => tc.Method); foreach (var method in methodGroups) { if (!messageBus.QueueMessage(new TestMethodStarting(collection, testClass.Name, method.Key.Name))) { cancellationTokenSource.Cancel(); } else { RunTestMethod(messageBus, constructorArguments.ToArray(), method, classSummary, aggregator, cancellationTokenSource); } if (!messageBus.QueueMessage(new TestMethodFinished(collection, testClass.Name, method.Key.Name))) { cancellationTokenSource.Cancel(); } if (cancellationTokenSource.IsCancellationRequested) { break; } } foreach (var fixture in fixtureMappings.Values.OfType <IDisposable>()) { try { fixture.Dispose(); } catch (Exception ex) { if (!messageBus.QueueMessage(new ErrorMessage(ex.Unwrap()))) { cancellationTokenSource.Cancel(); } } } }