/// <inheritdoc/> public IEnumerable <IXunitTestCase> Discover(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute) { var defaultMethodDisplay = discoveryOptions.MethodDisplayOrDefault(); // Special case Skip, because we want a single Skip (not one per data item), and a skipped test may // not actually have any data (which is quasi-legal, since it's skipped). if (factAttribute.GetNamedArgument <string>("Skip") != null) { return new[] { new XunitTestCase(defaultMethodDisplay, testMethod) } } ; var dataAttributes = testMethod.Method.GetCustomAttributes(typeof(DataAttribute)); if (discoveryOptions.PreEnumerateTheoriesOrDefault()) { try { var results = new List <XunitTestCase>(); foreach (var dataAttribute in dataAttributes) { var discovererAttribute = dataAttribute.GetCustomAttributes(typeof(DataDiscovererAttribute)).First(); var discoverer = ExtensibilityPointFactory.GetDataDiscoverer(discovererAttribute); if (!discoverer.SupportsDiscoveryEnumeration(dataAttribute, testMethod.Method)) { return new XunitTestCase[] { new XunitTheoryTestCase(defaultMethodDisplay, testMethod) } } ; // GetData may return null, but that's okay; we'll let the NullRef happen and then catch it // down below so that we get the composite test case. foreach (var dataRow in discoverer.GetData(dataAttribute, testMethod.Method)) { // Attempt to serialize the test case, since we need a way to uniquely identify a test // and serialization is the best way to do that. If it's not serializable, this will // throw and we will fall back to a single theory test case that gets its data // at runtime. var testCase = new XunitTestCase(defaultMethodDisplay, testMethod, dataRow); SerializationHelper.Serialize(testCase); results.Add(testCase); } } // REVIEW: Could we re-write LambdaTestCase to just be for exceptions? if (results.Count == 0) { results.Add(new LambdaTestCase(defaultMethodDisplay, testMethod, () => { throw new InvalidOperationException(String.Format("No data found for {0}.{1}", testMethod.TestClass.Class.Name, testMethod.Method.Name)); })); } return(results); } catch { } } return(new XunitTestCase[] { new XunitTheoryTestCase(defaultMethodDisplay, testMethod) }); } }
static ITestCaseOrderer GetXunitTestCaseOrderer(IAttributeInfo ordererAttribute) { var args = ordererAttribute.GetConstructorArguments().Cast <string>().ToList(); var ordererType = Reflector.GetType(args[1], args[0]); return(ExtensibilityPointFactory.GetTestCaseOrderer(ordererType)); }
/// <inheritdoc/> protected override void Initialize() { base.Initialize(); var factAttribute = TestMethod.Method.GetCustomAttributes(typeof(FactAttribute)).Single(); var baseDisplayName = factAttribute.GetNamedArgument <string>("DisplayName") ?? BaseDisplayName; DisplayName = TypeUtility.GetDisplayNameWithArguments(TestMethod.Method, baseDisplayName, TestMethodArguments, MethodGenericTypes); SkipReason = factAttribute.GetNamedArgument <string>("Skip"); foreach (var traitAttribute in TestMethod.Method.GetCustomAttributes(typeof(ITraitAttribute)) .Concat(TestMethod.TestClass.Class.GetCustomAttributes(typeof(ITraitAttribute)))) { var discovererAttribute = traitAttribute.GetCustomAttributes(typeof(TraitDiscovererAttribute)).FirstOrDefault(); if (discovererAttribute != null) { var discoverer = ExtensibilityPointFactory.GetTraitDiscoverer(discovererAttribute); if (discoverer != null) { foreach (var keyValuePair in discoverer.GetTraits(traitAttribute)) { Traits.Add(keyValuePair.Key, keyValuePair.Value); } } } // TODO: Log an environmental warning about the missing discoverer attribute } }
/// <inheritdoc/> protected override void OnAssemblyStarting() { collectionBehaviorAttribute = AssemblyInfo.GetCustomAttributes(typeof(CollectionBehaviorAttribute)).SingleOrDefault(); if (collectionBehaviorAttribute != null) { disableParallelization = collectionBehaviorAttribute.GetNamedArgument <bool>("DisableTestParallelization"); maxParallelThreads = collectionBehaviorAttribute.GetNamedArgument <int>("MaxParallelThreads"); } disableParallelization = ExecutionOptions.GetValue <bool>(TestOptionsNames.Execution.DisableParallelization, disableParallelization); var maxParallelThreadsOption = ExecutionOptions.GetValue <int>(TestOptionsNames.Execution.MaxParallelThreads, 0); if (maxParallelThreadsOption > 0) { maxParallelThreads = maxParallelThreadsOption; } scheduler = GetTaskScheduler(maxParallelThreads); var ordererAttribute = AssemblyInfo.GetCustomAttributes(typeof(TestCaseOrdererAttribute)).SingleOrDefault(); if (ordererAttribute != null) { TestCaseOrderer = ExtensibilityPointFactory.GetTestCaseOrderer(ordererAttribute); } }
void Initialize() { if (initialized) { return; } collectionBehaviorAttribute = TestAssembly.Assembly.GetCustomAttributes(typeof(CollectionBehaviorAttribute)).SingleOrDefault(); if (collectionBehaviorAttribute != null) { disableParallelization = collectionBehaviorAttribute.GetNamedArgument <bool>("DisableTestParallelization"); maxParallelThreads = collectionBehaviorAttribute.GetNamedArgument <int>("MaxParallelThreads"); } disableParallelization = ExecutionOptions.GetValue <bool>(TestOptionsNames.Execution.DisableParallelization, disableParallelization); var maxParallelThreadsOption = ExecutionOptions.GetValue <int>(TestOptionsNames.Execution.MaxParallelThreads, 0); if (maxParallelThreadsOption > 0) { maxParallelThreads = maxParallelThreadsOption; } scheduler = GetTaskScheduler(maxParallelThreads); var ordererAttribute = TestAssembly.Assembly.GetCustomAttributes(typeof(TestCaseOrdererAttribute)).SingleOrDefault(); if (ordererAttribute != null) { TestCaseOrderer = ExtensibilityPointFactory.GetTestCaseOrderer(ordererAttribute); } initialized = true; }
/// <summary> /// Get the traits from a method. /// </summary> /// <param name="member">The member (method, field, etc.) to get the traits for.</param> /// <returns>A list of traits that are defined on the method.</returns> public static IReadOnlyList <KeyValuePair <string, string> > GetTraits(MemberInfo member) { var messageSink = new NullMessageSink(); var result = new List <KeyValuePair <string, string> >(); foreach (var traitAttributeData in member.CustomAttributes) { var traitAttributeType = traitAttributeData.AttributeType; if (!typeof(ITraitAttribute).GetTypeInfo().IsAssignableFrom(traitAttributeType.GetTypeInfo())) { continue; } var discovererAttributeData = traitAttributeType.GetTypeInfo().CustomAttributes.FirstOrDefault(cad => cad.AttributeType == typeof(TraitDiscovererAttribute)); if (discovererAttributeData == null) { continue; } var discoverer = ExtensibilityPointFactory.GetTraitDiscoverer(messageSink, Reflector.Wrap(discovererAttributeData)); if (discoverer == null) { continue; } var traits = discoverer.GetTraits(Reflector.Wrap(traitAttributeData)); if (traits != null) { result.AddRange(traits); } } return(result); }
static Type GetTestFrameworkType(IAssemblyInfo testAssembly, IMessageSink diagnosticMessageSink) { try { var testFrameworkAttr = testAssembly.GetCustomAttributes(typeof(ITestFrameworkAttribute)).FirstOrDefault(); if (testFrameworkAttr != null) { var discovererAttr = testFrameworkAttr.GetCustomAttributes(typeof(TestFrameworkDiscovererAttribute)).FirstOrDefault(); if (discovererAttr != null) { var discoverer = ExtensibilityPointFactory.GetTestFrameworkTypeDiscoverer(diagnosticMessageSink, discovererAttr); if (discoverer != null) { return(discoverer.GetTestFrameworkType(testFrameworkAttr)); } var ctorArgs = discovererAttr.GetConstructorArguments().ToArray(); diagnosticMessageSink.OnMessage(new DiagnosticMessage($"Unable to create custom test framework discoverer type '{ctorArgs[1]}, {ctorArgs[0]}'")); } else { diagnosticMessageSink.OnMessage(new DiagnosticMessage("Assembly-level test framework attribute was not decorated with [TestFrameworkDiscoverer]")); } } } catch (Exception ex) { diagnosticMessageSink.OnMessage(new DiagnosticMessage($"Exception thrown during test framework discoverer construction: {ex.Unwrap()}")); } return(typeof(XunitTestFramework)); }
/// <summary> /// Get the traits from a method. /// </summary> /// <param name="member">The member (method, field, etc.) to get the traits for.</param> /// <returns>A list of traits that are defined on the method.</returns> public static IReadOnlyList <KeyValuePair <string, string> > GetTraits(MemberInfo member) { Guard.ArgumentNotNull(member); var result = new List <KeyValuePair <string, string> >(); foreach (var traitAttributeData in member.CustomAttributes) { var traitAttributeType = traitAttributeData.AttributeType; if (!typeof(ITraitAttribute).IsAssignableFrom(traitAttributeType)) { continue; } var discovererAttributeData = FindDiscovererAttributeType(traitAttributeType); if (discovererAttributeData == null) { continue; } var discoverer = ExtensibilityPointFactory.GetTraitDiscoverer(Reflector.Wrap(discovererAttributeData)); if (discoverer == null) { continue; } var traits = discoverer.GetTraits(Reflector.Wrap(traitAttributeData)); if (traits != null) { result.AddRange(traits); } } return(result); }
/// <summary> /// Gives an opportunity to override test case orderer. By default, this method gets the /// orderer from the collection definition. If this function returns <c>null</c>, the /// test case orderer passed into the constructor will be used. /// </summary> protected virtual ITestCaseOrderer GetTestCaseOrderer() { if (TestCollection.CollectionDefinition != null) { var ordererAttribute = TestCollection.CollectionDefinition.GetCustomAttributes(typeof(TestCaseOrdererAttribute)).SingleOrDefault(); if (ordererAttribute != null) { try { var testCaseOrderer = ExtensibilityPointFactory.GetTestCaseOrderer(DiagnosticMessageSink, ordererAttribute); if (testCaseOrderer != null) { return(testCaseOrderer); } var args = ordererAttribute.GetConstructorArguments().Cast <string>().ToList(); DiagnosticMessageSink.OnMessage(new DiagnosticMessage($"Could not find type '{args[0]}' in {args[1]} for collection-level test case orderer on test collection '{TestCollection.DisplayName}'")); } catch (Exception ex) { var innerEx = ex.Unwrap(); var args = ordererAttribute.GetConstructorArguments().Cast <string>().ToList(); DiagnosticMessageSink.OnMessage(new DiagnosticMessage($"Collection-level test case orderer '{args[0]}' for test collection '{TestCollection.DisplayName}' threw '{innerEx.GetType().FullName}' during construction: {innerEx.Message}{Environment.NewLine}{innerEx.StackTrace}")); } } } return(null); }
/// <inheritdoc/> protected override void Initialize() { base.Initialize(); var factAttribute = TestMethod.Method.GetCustomAttributes(typeof(FactAttribute)).Single(); var baseDisplayName = factAttribute.GetNamedArgument <string>("DisplayName") ?? BaseDisplayName; DisplayName = TypeUtility.GetDisplayNameWithArguments(TestMethod.Method, baseDisplayName, TestMethodArguments, MethodGenericTypes); SkipReason = factAttribute.GetNamedArgument <string>("Skip"); foreach (var traitAttribute in TestMethod.Method.GetCustomAttributes(typeof(ITraitAttribute)) .Concat(TestMethod.TestClass.Class.GetCustomAttributes(typeof(ITraitAttribute)))) { var discovererAttribute = traitAttribute.GetCustomAttributes(typeof(TraitDiscovererAttribute)).FirstOrDefault(); if (discovererAttribute != null) { var discoverer = ExtensibilityPointFactory.GetTraitDiscoverer(diagnosticMessageSink, discovererAttribute); if (discoverer != null) { foreach (var keyValuePair in discoverer.GetTraits(traitAttribute)) { Traits.Add(keyValuePair.Key, keyValuePair.Value); } } } else { diagnosticMessageSink.OnMessage(new DiagnosticMessage("Trait attribute on '{0}' did not have [TraitDiscoverer]", DisplayName)); } } }
/// <inheritdoc/> protected override Task AfterTestClassStartingAsync() { var ordererAttribute = Class.GetCustomAttributes(typeof(TestCaseOrdererAttribute)).SingleOrDefault(); if (ordererAttribute != null) { TestCaseOrderer = ExtensibilityPointFactory.GetTestCaseOrderer(ordererAttribute); } var testClassTypeInfo = Class.Type.GetTypeInfo(); if (testClassTypeInfo.ImplementedInterfaces.Any(i => i.GetTypeInfo().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 testClassTypeInfo.ImplementedInterfaces.Where(i => i.GetTypeInfo().IsGenericType&& i.GetGenericTypeDefinition() == typeof(IClassFixture <>))) { CreateFixture(interfaceType); } if (TestClass.TestCollection.CollectionDefinition != null) { var declarationType = ((IReflectionTypeInfo)TestClass.TestCollection.CollectionDefinition).Type; foreach (var interfaceType in declarationType.GetTypeInfo().ImplementedInterfaces.Where(i => i.GetTypeInfo().IsGenericType&& i.GetGenericTypeDefinition() == typeof(IClassFixture <>))) { CreateFixture(interfaceType); } } return(Task.FromResult(0)); }
/// <inheritdoc/> protected override void Initialize() { base.Initialize(); var factAttribute = TestMethod.Method.GetCustomAttributes(typeof(FactAttribute)).First(); var baseDisplayName = factAttribute.GetNamedArgument <string>("DisplayName") ?? BaseDisplayName; DisplayName = GetDisplayName(factAttribute, baseDisplayName); SkipReason = GetSkipReason(factAttribute); foreach (var traitAttribute in GetTraitAttributesData(TestMethod)) { var discovererAttribute = traitAttribute.GetCustomAttributes(typeof(TraitDiscovererAttribute)).FirstOrDefault(); if (discovererAttribute != null) { var discoverer = ExtensibilityPointFactory.GetTraitDiscoverer(DiagnosticMessageSink, discovererAttribute); if (discoverer != null) { foreach (var keyValuePair in discoverer.GetTraits(traitAttribute)) { Traits.Add(keyValuePair.Key, keyValuePair.Value); } } } else { DiagnosticMessageSink.OnMessage(new DiagnosticMessage($"Trait attribute on '{DisplayName}' did not have [TraitDiscoverer]")); } } }
/// <inheritdoc/> protected override string GetTestFrameworkEnvironment() { Initialize(); var testCollectionFactory = ExtensibilityPointFactory.GetXunitTestCollectionFactory(DiagnosticMessageSink, collectionBehaviorAttribute, TestAssembly); return($"{base.GetTestFrameworkEnvironment()} [{testCollectionFactory.DisplayName}, {(disableParallelization ? "non-parallel" : "parallel")}{(maxParallelThreads > 0 ? $" ({maxParallelThreads} threads)" : "")}]"); }
/// <inheritdoc/> protected override string GetTestFrameworkEnvironment() { Initialize(); var testCollectionFactory = ExtensibilityPointFactory.GetXunitTestCollectionFactory(DiagnosticMessageSink, collectionBehaviorAttribute, TestAssembly); var threadCountText = maxParallelThreads < 0 ? "unlimited" : maxParallelThreads.ToString(); return($"{base.GetTestFrameworkEnvironment()} [{testCollectionFactory.DisplayName}, {(disableParallelization ? "non-parallel" : $"parallel ({threadCountText} threads)")}]");
/// <inheritdoc/> public async void Dispose() { // We want to immediately return before we call DisconnectAll, since we are in the list // of things that will be disconnected. await Task.Delay(1); ExtensibilityPointFactory.Dispose(); DisposalTracker.Dispose(); LongLivedMarshalByRefObject.DisconnectAll(); }
/// <inheritdoc/> protected override string GetTestFrameworkEnvironment() { var testCollectionFactory = ExtensibilityPointFactory.GetXunitTestCollectionFactory(collectionBehaviorAttribute, AssemblyInfo); return(String.Format("{0}-bit .NET {1} [{2}, {3}{4}]", IntPtr.Size * 8, Environment.Version, testCollectionFactory.DisplayName, disableParallelization ? "non-parallel" : "parallel", maxParallelThreads > 0 ? String.Format(" (max {0} threads)", maxParallelThreads) : "")); }
/// <inheritdoc/> protected override string GetTestFrameworkEnvironment() { Initialize(); var testCollectionFactory = ExtensibilityPointFactory.GetXunitTestCollectionFactory(DiagnosticMessageSink, collectionBehaviorAttribute, TestAssembly); return(String.Format("{0} [{1}, {2}{3}]", base.GetTestFrameworkEnvironment(), testCollectionFactory.DisplayName, disableParallelization ? "non-parallel" : "parallel", maxParallelThreads > 0 ? String.Format(" ({0} threads)", maxParallelThreads) : "")); }
/// <inheritdoc/> public IEnumerable <IXunitTestCase> Discover(ITestCollection testCollection, IAssemblyInfo assembly, ITypeInfo testClass, IMethodInfo testMethod, IAttributeInfo factAttribute) { // Special case Skip, because we want a single Skip (not one per data item), and a skipped test may // not actually have any data (which is quasi-legal, since it's skipped). if (factAttribute.GetNamedArgument <string>("Skip") != null) { return new[] { new XunitTestCase(testCollection, assembly, testClass, testMethod, factAttribute) } } ; try { using (var memoryStream = new MemoryStream()) { var results = new List <XunitTestCase>(); var dataAttributes = testMethod.GetCustomAttributes(typeof(DataAttribute)); foreach (var dataAttribute in dataAttributes) { var discovererAttribute = dataAttribute.GetCustomAttributes(typeof(DataDiscovererAttribute)).First(); var args = discovererAttribute.GetConstructorArguments().Cast <string>().ToList(); var discovererType = Reflector.GetType(args[1], args[0]); var discoverer = ExtensibilityPointFactory.GetDataDiscoverer(discovererType); // GetData may return null, but that's okay; we'll let the NullRef happen and then catch it // down below so that we get the composite test case. foreach (object[] dataRow in discoverer.GetData(dataAttribute, testMethod)) { // Attempt to serialize the test case, since we need a way to uniquely identify a test // and serialization is the best way to do that. If it's not serializable, this will // throw and we will fall back to a single theory test case that gets its data // at runtime. var testCase = new XunitTestCase(testCollection, assembly, testClass, testMethod, factAttribute, dataRow); SerializationHelper.Serialize(testCase); results.Add(testCase); } } // REVIEW: Could we re-write LambdaTestCase to just be for exceptions? if (results.Count == 0) { results.Add(new LambdaTestCase(testCollection, assembly, testClass, testMethod, factAttribute, () => { throw new InvalidOperationException("No data found for " + testClass.Name + "." + testMethod.Name); })); } return(results); } } catch { return(new XunitTestCase[] { new XunitTheoryTestCase(testCollection, assembly, testClass, testMethod, factAttribute) }); } } }
/// <summary> /// Gets the test case discover instance for the given discoverer type. The instances are cached /// and reused, since they should not be stateful. /// </summary> /// <param name="discovererType">The discoverer type.</param> /// <returns>Returns the test case discoverer instance.</returns> protected IXunitTestCaseDiscoverer GetDiscoverer(Type discovererType) { try { return(ExtensibilityPointFactory.GetXunitTestCaseDiscoverer(DiagnosticMessageSink, discovererType)); } catch (Exception ex) { DiagnosticMessageSink.OnMessage(new DiagnosticMessage($"Discoverer type '{discovererType.FullName}' could not be created or does not implement IXunitTestCaseDiscoverer: {ex.Unwrap()}")); return(null); } }
/// <inheritdoc/> protected override async Task AfterTestClassStartingAsync() { 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 '{TestClass.Class.Name}'")); } } catch (Exception ex) { var innerEx = ex.Unwrap(); var args = ordererAttribute.GetConstructorArguments().Cast <string>().ToList(); DiagnosticMessageSink.OnMessage(new DiagnosticMessage($"Class-level test case orderer '{args[0]}' for test class '{TestClass.Class.Name}' threw '{innerEx.GetType().FullName}' during construction: {innerEx.Message}{Environment.NewLine}{innerEx.StackTrace}")); } } var testClassTypeInfo = Class.Type.GetTypeInfo(); if (testClassTypeInfo.ImplementedInterfaces.Any(i => i.GetTypeInfo().IsGenericType&& i.GetGenericTypeDefinition() == typeof(ICollectionFixture <>))) { Aggregator.Add(new TestClassException("A test class may not be decorated with ICollectionFixture<> (decorate the test collection class instead).")); } var createClassFixtureAsyncTasks = new List <Task>(); foreach (var interfaceType in testClassTypeInfo.ImplementedInterfaces.Where(i => i.GetTypeInfo().IsGenericType&& i.GetGenericTypeDefinition() == typeof(IClassFixture <>))) { createClassFixtureAsyncTasks.Add(CreateClassFixtureAsync(interfaceType.GetTypeInfo().GenericTypeArguments.Single())); } if (TestClass.TestCollection.CollectionDefinition != null) { var declarationType = ((IReflectionTypeInfo)TestClass.TestCollection.CollectionDefinition).Type; foreach (var interfaceType in declarationType.GetTypeInfo().ImplementedInterfaces.Where(i => i.GetTypeInfo().IsGenericType&& i.GetGenericTypeDefinition() == typeof(IClassFixture <>))) { createClassFixtureAsyncTasks.Add(CreateClassFixtureAsync(interfaceType.GetTypeInfo().GenericTypeArguments.Single())); } } await Task.WhenAll(createClassFixtureAsyncTasks); }
/// <inheritdoc/> protected override async Task AfterTestCaseStartingAsync() { await base.AfterTestCaseStartingAsync(); try { var dataAttributes = TestCase.TestMethod.Method.GetCustomAttributes(typeof(DataAttribute)); foreach (var dataAttribute in dataAttributes) { var discovererAttribute = dataAttribute.GetCustomAttributes(typeof(DataDiscovererAttribute)).First(); var args = discovererAttribute.GetConstructorArguments().Cast <string>().ToList(); var discovererType = SerializationHelper.GetType(args[1], args[0]); var discoverer = ExtensibilityPointFactory.GetDataDiscoverer(diagnosticMessageSink, discovererType); IEnumerable <object[]> data = discoverer.GetData(dataAttribute, TestCase.TestMethod.Method); if (data == null) { Aggregator.Add(new InvalidOperationException($"Test data returned null for {TestCase.TestMethod.TestClass.Class.Name}.{TestCase.TestMethod.Method.Name}. Make sure it is statically initialized before this test method is called.")); continue; } foreach (var dataRow in data) { toDispose.AddRange(dataRow.OfType <IDisposable>()); ITypeInfo[] resolvedTypes = null; var methodToRun = TestMethod; var convertedDataRow = methodToRun.ResolveMethodArguments(dataRow); if (methodToRun.IsGenericMethodDefinition) { resolvedTypes = TestCase.TestMethod.Method.ResolveGenericTypes(convertedDataRow); methodToRun = methodToRun.MakeGenericMethod(resolvedTypes.Select(t => ((IReflectionTypeInfo)t).Type).ToArray()); } var parameterTypes = methodToRun.GetParameters().Select(p => p.ParameterType).ToArray(); convertedDataRow = Reflector.ConvertArguments(convertedDataRow, parameterTypes); var theoryDisplayName = TestCase.TestMethod.Method.GetDisplayNameWithArguments(DisplayName, convertedDataRow, resolvedTypes); var test = new XunitTest(TestCase, theoryDisplayName); var skipReason = SkipReason ?? dataAttribute.GetNamedArgument <string>("Skip"); testRunners.Add(new XunitTestRunner(test, MessageBus, TestClass, ConstructorArguments, methodToRun, convertedDataRow, skipReason, BeforeAfterAttributes, Aggregator, CancellationTokenSource)); } } } catch (Exception ex) { // Stash the exception so we can surface it during RunTestAsync dataDiscoveryException = ex; } }
/// <summary> /// Initializes a new instance of the <see cref="XunitTestFrameworkDiscoverer"/> class. /// </summary> /// <param name="assemblyInfo">The test assembly.</param> /// <param name="configFileName">The test configuration file.</param> /// <param name="sourceProvider">The source information provider.</param> /// <param name="diagnosticMessageSink">The message sink used to send diagnostic messages</param> /// <param name="collectionFactory">The test collection factory used to look up test collections.</param> public XunitTestFrameworkDiscoverer(IAssemblyInfo assemblyInfo, string configFileName, ISourceInformationProvider sourceProvider, IMessageSink diagnosticMessageSink, IXunitTestCollectionFactory collectionFactory = null) : base(assemblyInfo, sourceProvider, diagnosticMessageSink) { var collectionBehaviorAttribute = assemblyInfo.GetCustomAttributes(typeof(CollectionBehaviorAttribute)).SingleOrDefault(); var disableParallelization = collectionBehaviorAttribute != null && collectionBehaviorAttribute.GetNamedArgument <bool>("DisableTestParallelization"); var testAssembly = new TestAssembly(assemblyInfo, configFileName); TestCollectionFactory = collectionFactory ?? ExtensibilityPointFactory.GetXunitTestCollectionFactory(diagnosticMessageSink, collectionBehaviorAttribute, testAssembly); TestFrameworkDisplayName = $"{DisplayName} [{TestCollectionFactory.DisplayName}, {(disableParallelization ? "non-parallel" : "parallel")}]"; }
/// <summary> /// Initializes a new instance of the <see cref="XunitTestFrameworkDiscoverer"/> class. /// </summary> /// <param name="assemblyInfo">The test assembly.</param> /// <param name="sourceProvider">The source information provider.</param> /// <param name="collectionFactory">The test collection factory used to look up test collections.</param> /// <param name="messageAggregator">The message aggregator to receive environmental warnings from.</param> public XunitTestFrameworkDiscoverer(IAssemblyInfo assemblyInfo, ISourceInformationProvider sourceProvider, IXunitTestCollectionFactory collectionFactory, IMessageAggregator messageAggregator) : base(assemblyInfo, sourceProvider, messageAggregator) { var collectionBehaviorAttribute = assemblyInfo.GetCustomAttributes(typeof(CollectionBehaviorAttribute)).SingleOrDefault(); var disableParallelization = collectionBehaviorAttribute == null ? false : collectionBehaviorAttribute.GetNamedArgument <bool>("DisableTestParallelization"); TestCollectionFactory = collectionFactory ?? ExtensibilityPointFactory.GetXunitTestCollectionFactory(collectionBehaviorAttribute, AssemblyInfo); TestFrameworkDisplayName = String.Format("{0} [{1}, {2}]", DisplayName, TestCollectionFactory.DisplayName, disableParallelization ? "non-parallel" : "parallel"); }
/// <summary> /// Initializes a new instance of the <see cref="TestFrameworkProxy"/> class. /// </summary> /// <param name="testAssemblyObject">The test assembly (expected to implement <see cref="IAssemblyInfo"/>).</param> /// <param name="sourceInformationProviderObject">The source information provider (expected to implement <see cref="ISourceInformationProvider"/>).</param> public TestFrameworkProxy(object testAssemblyObject, object sourceInformationProviderObject) { #if PLATFORM_LINUX || PLATFORM_MACOS InnerTestFramework = new XunitTestFramework(); SourceInformationProvider = new NullMonoSourceInformationProvider(); #else var testAssembly = (IAssemblyInfo)testAssemblyObject; var sourceInformationProvider = (ISourceInformationProvider)sourceInformationProviderObject; var testFrameworkType = typeof(XunitTestFramework); try { var testFrameworkAttr = testAssembly.GetCustomAttributes(typeof(ITestFrameworkAttribute)).FirstOrDefault(); if (testFrameworkAttr != null) { var discovererAttr = testFrameworkAttr.GetCustomAttributes(typeof(TestFrameworkDiscovererAttribute)).FirstOrDefault(); if (discovererAttr != null) { var discoverer = ExtensibilityPointFactory.GetTestFrameworkTypeDiscoverer(discovererAttr); if (discoverer != null) { testFrameworkType = discoverer.GetTestFrameworkType(testFrameworkAttr); } // else // TODO: Log environmental error } // else // TODO: Log environmental error } } catch { // TODO: Log environmental error } try { InnerTestFramework = (ITestFramework)Activator.CreateInstance(testFrameworkType); } catch { // TODO: Log environmental error InnerTestFramework = new XunitTestFramework(); } SourceInformationProvider = sourceInformationProvider; #endif }
/// <inheritdoc/> protected override void AfterTestCollectionStarting() { if (TestCollection.CollectionDefinition != null) { var declarationType = ((IReflectionTypeInfo)TestCollection.CollectionDefinition).Type; foreach (var interfaceType in declarationType.GetTypeInfo().ImplementedInterfaces.Where(i => i.GetTypeInfo().IsGenericType&& i.GetGenericTypeDefinition() == typeof(ICollectionFixture <>))) { CreateFixture(interfaceType); } var ordererAttribute = TestCollection.CollectionDefinition.GetCustomAttributes(typeof(TestCaseOrdererAttribute)).SingleOrDefault(); if (ordererAttribute != null) { TestCaseOrderer = ExtensibilityPointFactory.GetTestCaseOrderer(ordererAttribute); } } }
/// <summary> /// Gets the test case discover instance for the given discoverer type. The instances are cached /// and reused, since they should not be stateful. /// </summary> /// <param name="discovererType">The discoverer type.</param> /// <returns>Returns the test case discoverer instance.</returns> protected IXunitTestCaseDiscoverer GetDiscoverer(Type discovererType) { if (!discovererCache.TryGetValue(discovererType, out IXunitTestCaseDiscoverer result)) { try { result = ExtensibilityPointFactory.GetXunitTestCaseDiscoverer(DiagnosticMessageSink, discovererType); } catch (Exception ex) { result = null; DiagnosticMessageSink.OnMessage(new DiagnosticMessage($"Discoverer type '{discovererType.FullName}' could not be created or does not implement IXunitTestCaseDiscoverer: {ex.Unwrap()}")); } discovererCache[discovererType] = result; } return(result); }
/// <summary> /// Initializes a new instance of the <see cref="XunitTestFrameworkDiscoverer"/> class. /// </summary> /// <param name="assemblyInfo">The test assembly.</param> /// <param name="sourceProvider">The source information provider.</param> /// <param name="diagnosticMessageSink">The message sink used to send diagnostic messages</param> /// <param name="collectionFactory">The test collection factory used to look up test collections.</param> public XunitTestFrameworkDiscoverer(IAssemblyInfo assemblyInfo, ISourceInformationProvider sourceProvider, IMessageSink diagnosticMessageSink, IXunitTestCollectionFactory collectionFactory = null) : base(assemblyInfo, sourceProvider, diagnosticMessageSink) { var collectionBehaviorAttribute = assemblyInfo.GetCustomAttributes(typeof(CollectionBehaviorAttribute)).SingleOrDefault(); var disableParallelization = collectionBehaviorAttribute != null && collectionBehaviorAttribute.GetNamedArgument <bool>("DisableTestParallelization"); string config = null; #if !WINDOWS_PHONE_APP && !WINDOWS_PHONE && !DOTNETCORE config = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; #endif var testAssembly = new TestAssembly(assemblyInfo, config); TestCollectionFactory = collectionFactory ?? ExtensibilityPointFactory.GetXunitTestCollectionFactory(diagnosticMessageSink, collectionBehaviorAttribute, testAssembly); TestFrameworkDisplayName = $"{DisplayName} [{TestCollectionFactory.DisplayName}, {(disableParallelization ? "non-parallel" : "parallel")}]"; }
/// <inheritdoc/> protected override async Task AfterTestCaseStartingAsync() { await base.AfterTestCaseStartingAsync(); try { var dataAttributes = TestCase.TestMethod.Method.GetCustomAttributes(typeof(DataAttribute)); foreach (var dataAttribute in dataAttributes) { var discovererAttribute = dataAttribute.GetCustomAttributes(typeof(DataDiscovererAttribute)).First(); var args = discovererAttribute.GetConstructorArguments().Cast <string>().ToList(); var discovererType = Reflector.GetType(args[1], args[0]); var discoverer = ExtensibilityPointFactory.GetDataDiscoverer(discovererType); foreach (var dataRow in discoverer.GetData(dataAttribute, TestCase.TestMethod.Method)) { toDispose.AddRange(dataRow.OfType <IDisposable>()); ITypeInfo[] resolvedTypes = null; var methodToRun = TestMethod; if (methodToRun.IsGenericMethodDefinition) { resolvedTypes = TypeUtility.ResolveGenericTypes(TestCase.TestMethod.Method, dataRow); methodToRun = methodToRun.MakeGenericMethod(resolvedTypes.Select(t => ((IReflectionTypeInfo)t).Type).ToArray()); } var parameterTypes = methodToRun.GetParameters().Select(p => p.ParameterType).ToArray(); var convertedDataRow = Reflector.ConvertArguments(dataRow, parameterTypes); var theoryDisplayName = TypeUtility.GetDisplayNameWithArguments(TestCase.TestMethod.Method, DisplayName, convertedDataRow, resolvedTypes); var test = new XunitTest(TestCase, theoryDisplayName); testRunners.Add(new XunitTestRunner(test, MessageBus, TestClass, ConstructorArguments, methodToRun, convertedDataRow, SkipReason, BeforeAfterAttributes, Aggregator, CancellationTokenSource)); } } } catch (Exception ex) { // Stash the exception so we can surface it during RunTestAsync dataDiscoveryException = ex; } }
void Initialize(ITestCollection testCollection, IAssemblyInfo assembly, ITypeInfo type, IMethodInfo method, IAttributeInfo factAttribute, object[] arguments) { string displayNameBase = factAttribute.GetNamedArgument <string>("DisplayName") ?? type.Name + "." + method.Name; ITypeInfo[] resolvedTypes = null; if (arguments != null && method.IsGenericMethodDefinition) { resolvedTypes = ResolveGenericTypes(method, arguments); method = method.MakeGenericMethod(resolvedTypes); } Assembly = assembly; Class = type; Method = method; Arguments = arguments; DisplayName = GetDisplayNameWithArguments(displayNameBase, arguments, resolvedTypes); SkipReason = factAttribute.GetNamedArgument <string>("Skip"); Traits = new Dictionary <string, List <string> >(StringComparer.OrdinalIgnoreCase); TestCollection = testCollection; foreach (var traitAttribute in Method.GetCustomAttributes(typeof(ITraitAttribute)) .Concat(Class.GetCustomAttributes(typeof(ITraitAttribute)))) { var discovererAttribute = traitAttribute.GetCustomAttributes(typeof(TraitDiscovererAttribute)).First(); var args = discovererAttribute.GetConstructorArguments().Cast <string>().ToList(); var discovererType = Reflector.GetType(args[1], args[0]); if (discovererType != null) { var discoverer = ExtensibilityPointFactory.GetTraitDiscoverer(discovererType); foreach (var keyValuePair in discoverer.GetTraits(traitAttribute)) { Traits.Add(keyValuePair.Key, keyValuePair.Value); } } } uniqueID = new Lazy <string>(GetUniqueID, true); }
/// <summary> /// Initializes a new instance of the <see cref="XunitTestFrameworkDiscoverer"/> class. /// </summary> /// <param name="assemblyInfo">The test assembly.</param> /// <param name="sourceProvider">The source information provider.</param> /// <param name="collectionFactory">The test collection factory used to look up test collections.</param> /// <param name="messageAggregator">The message aggregator to receive environmental warnings from.</param> public XunitTestFrameworkDiscoverer(IAssemblyInfo assemblyInfo, ISourceInformationProvider sourceProvider, IXunitTestCollectionFactory collectionFactory, IMessageAggregator messageAggregator) : base(assemblyInfo, sourceProvider, messageAggregator) { var collectionBehaviorAttribute = assemblyInfo.GetCustomAttributes(typeof(CollectionBehaviorAttribute)).SingleOrDefault(); var disableParallelization = collectionBehaviorAttribute == null ? false : collectionBehaviorAttribute.GetNamedArgument <bool>("DisableTestParallelization"); string config = null; #if !WINDOWS_PHONE_APP && !WINDOWS_PHONE && !ASPNETCORE50 config = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; #endif var testAssembly = new TestAssembly(assemblyInfo, config); TestCollectionFactory = collectionFactory ?? ExtensibilityPointFactory.GetXunitTestCollectionFactory(collectionBehaviorAttribute, testAssembly); TestFrameworkDisplayName = String.Format("{0} [{1}, {2}]", DisplayName, TestCollectionFactory.DisplayName, disableParallelization ? "non-parallel" : "parallel"); }