/// <summary> /// Gets the test framework object for the given test assembly. It is important that callers to this function have /// called <see cref="TestContext.SetForInitialization"/> before calling this, so that the test framework and /// any ancillary helper classes have access to the diagnostic and internal diagnostic message sinks. /// </summary> /// <param name="testAssembly">The test assembly to get the test framework for</param> /// <returns>The test framework object</returns> public static _ITestFramework GetTestFramework(_IAssemblyInfo testAssembly) { _ITestFramework result; var testFrameworkType = GetTestFrameworkType(testAssembly); if (!typeof(_ITestFramework).IsAssignableFrom(testFrameworkType)) { TestContext.Current?.SendDiagnosticMessage("Test framework type '{0}' does not implement '{1}'; falling back to '{2}'", testFrameworkType.FullName, typeof(_ITestFramework).FullName, typeof(XunitTestFramework).FullName); testFrameworkType = typeof(XunitTestFramework); } try { result = (_ITestFramework)Activator.CreateInstance(testFrameworkType) !; } catch (Exception ex) { TestContext.Current?.SendDiagnosticMessage("Exception thrown during test framework construction; falling back to default test framework: {0}", ex.Unwrap()); result = new XunitTestFramework(); } return(result); }
static Type GetTestFrameworkType(_IAssemblyInfo testAssembly) { try { var testFrameworkAttr = testAssembly.GetCustomAttributes(typeof(ITestFrameworkAttribute)).FirstOrDefault(); if (testFrameworkAttr != null) { var discovererAttr = testFrameworkAttr.GetCustomAttributes(typeof(TestFrameworkDiscovererAttribute)).FirstOrDefault(); if (discovererAttr != null) { var discoverer = GetTestFrameworkTypeDiscoverer(discovererAttr); if (discoverer != null) { var discovererType = discoverer.GetTestFrameworkType(testFrameworkAttr); if (discovererType != null) { return(discovererType); } } TestContext.Current?.SendDiagnosticMessage("Unable to create custom test framework discoverer type from '{0}'", testFrameworkAttr.GetType().FullName); } else { TestContext.Current?.SendDiagnosticMessage("Assembly-level test framework attribute was not decorated with [TestFrameworkDiscoverer]"); } } } catch (Exception ex) { TestContext.Current?.SendDiagnosticMessage("Exception thrown during test framework discoverer construction: {0}", ex.Unwrap()); } return(typeof(XunitTestFramework)); }
// Factory methods /// <summary> /// Returns an implementation of <see cref="IFrontControllerDiscoverer"/> which can be used /// to discover xUnit.net v2 tests, including source-based discovery. /// </summary> /// <param name="assemblyInfo">The assembly to use for discovery</param> /// <param name="projectAssembly">The test project assembly.</param> /// <param name="xunitExecutionAssemblyPath">The path on disk of xunit.execution.*.dll; if <c>null</c>, then /// the location of xunit.execution.*.dll is implied based on the location of the test assembly</param> /// <param name="sourceInformationProvider">The optional source information provider.</param> /// <param name="diagnosticMessageSink">The message sink which receives <see cref="_DiagnosticMessage"/> messages.</param> /// <param name="verifyAssembliesOnDisk">Determines whether or not to check for the existence of assembly files.</param> public static IFrontControllerDiscoverer ForDiscovery( _IAssemblyInfo assemblyInfo, XunitProjectAssembly projectAssembly, string?xunitExecutionAssemblyPath = null, _ISourceInformationProvider?sourceInformationProvider = null, _IMessageSink?diagnosticMessageSink = null, bool verifyAssembliesOnDisk = true) { var appDomainSupport = projectAssembly.Configuration.AppDomainOrDefault; Guard.ArgumentNotNull(assemblyInfo); return(new Xunit2( diagnosticMessageSink ?? _NullMessageSink.Instance, appDomainSupport, sourceInformationProvider ?? _NullSourceInformationProvider.Instance, // TODO: Need to find a way to be able to use VisualStudioSourceInformationProvider assemblyInfo, assemblyFileName: null, xunitExecutionAssemblyPath ?? GetXunitExecutionAssemblyPath(appDomainSupport, assemblyInfo), projectAssembly.ConfigFileName, projectAssembly.Configuration.ShadowCopyOrDefault, projectAssembly.Configuration.ShadowCopyFolder, verifyAssembliesOnDisk )); }
TestableXunitTestFrameworkDiscoverer( _IAssemblyInfo assemblyInfo, IXunitTestCollectionFactory?collectionFactory) : base(assemblyInfo, configFileName: null, collectionFactory) { TestAssembly = Mocks.TestAssembly(assemblyInfo.AssemblyPath, uniqueID: "asm-id"); }
/// <summary> /// Gets the test collection definitions for the given assembly. /// </summary> /// <param name="assemblyInfo">The assembly.</param> /// <param name="diagnosticMessageSink">The message sink which receives <see cref="_DiagnosticMessage"/> messages.</param> /// <returns>A list of mappings from test collection name to test collection definitions (as <see cref="_ITypeInfo"/></returns> public static Dictionary <string, _ITypeInfo> GetTestCollectionDefinitions( _IAssemblyInfo assemblyInfo, _IMessageSink diagnosticMessageSink) { var attributeTypesByName = assemblyInfo .GetTypes(false) .Select(type => new { Type = type, Attribute = type.GetCustomAttributes(typeof(CollectionDefinitionAttribute).AssemblyQualifiedName !).FirstOrDefault() })
/// <summary> /// Gets all the custom attributes for the given assembly. /// </summary> /// <param name="assemblyInfo">The assembly</param> /// <param name="attributeType">The type of the attribute</param> /// <returns>The matching attributes that decorate the assembly</returns> public static IReadOnlyCollection <_IAttributeInfo> GetCustomAttributes(this _IAssemblyInfo assemblyInfo, Type attributeType) { Guard.ArgumentNotNull(assemblyInfo); Guard.ArgumentNotNull(attributeType); Guard.NotNull("Attribute type cannot be a generic type parameter", attributeType.AssemblyQualifiedName); return(assemblyInfo.GetCustomAttributes(attributeType.AssemblyQualifiedName)); }
/// <summary> /// Gets all the custom attributes for the given assembly. /// </summary> /// <param name="assemblyInfo">The assembly</param> /// <param name="attributeType">The type of the attribute</param> /// <returns>The matching attributes that decorate the assembly</returns> public static IEnumerable <_IAttributeInfo> GetCustomAttributes(this _IAssemblyInfo assemblyInfo, Type attributeType) { Guard.ArgumentNotNull(nameof(assemblyInfo), assemblyInfo); Guard.ArgumentNotNull(nameof(attributeType), attributeType); Guard.NotNull("Attribute type cannot be a generic type parameter", attributeType.AssemblyQualifiedName); return(assemblyInfo.GetCustomAttributes(attributeType.AssemblyQualifiedName)); }
static string GetXunitExecutionAssemblyPath( AppDomainSupport appDomainSupport, _IAssemblyInfo assemblyInfo) { Guard.ArgumentNotNull(assemblyInfo); Guard.ArgumentNotNullOrEmpty(assemblyInfo.AssemblyPath); return(GetExecutionAssemblyFileName(appDomainSupport, Path.GetDirectoryName(assemblyInfo.AssemblyPath) !)); }
protected TestableXunitTestFrameworkDiscoverer( _IAssemblyInfo assembly, _ISourceInformationProvider?sourceProvider, _IMessageSink?diagnosticMessageSink, IXunitTestCollectionFactory?collectionFactory) : base(assembly, configFileName: null, sourceProvider ?? Substitute.For <_ISourceInformationProvider>(), diagnosticMessageSink ?? new _NullMessageSink(), collectionFactory) { Assembly = assembly; Sink = new TestableTestDiscoverySink(); }
/// <summary/> public PreserveWorkingFolder(_IAssemblyInfo assemblyInfo) { originalWorkingFolder = Directory.GetCurrentDirectory(); if (!string.IsNullOrWhiteSpace(assemblyInfo.AssemblyPath)) { var assemblyFolder = Path.GetDirectoryName(assemblyInfo.AssemblyPath); if (!string.IsNullOrWhiteSpace(assemblyFolder)) { Directory.SetCurrentDirectory(assemblyFolder); } } }
/// <summary> /// Initializes a new instance of the <see cref="TestFrameworkDiscoverer"/> class. /// </summary> /// <param name="assemblyInfo">The test assembly.</param> /// <param name="configFileName">The configuration filename.</param> /// <param name="sourceProvider">The source information provider.</param> /// <param name="diagnosticMessageSink">The message sink which receives <see cref="_DiagnosticMessage"/> messages.</param> protected TestFrameworkDiscoverer( _IAssemblyInfo assemblyInfo, string?configFileName, _ISourceInformationProvider sourceProvider, _IMessageSink diagnosticMessageSink) { this.assemblyInfo = Guard.ArgumentNotNull(nameof(assemblyInfo), assemblyInfo); this.configFileName = configFileName; this.diagnosticMessageSink = Guard.ArgumentNotNull(nameof(diagnosticMessageSink), diagnosticMessageSink); this.sourceProvider = Guard.ArgumentNotNull(nameof(sourceProvider), sourceProvider); targetFramework = new Lazy <string>(() => AssemblyInfo.GetTargetFramework()); }
// Factory methods /// <summary> /// Returns an implementation of <see cref="IFrontControllerDiscoverer"/> which can be /// used to discovery tests, including source-based discovery (note that xUnit.net v1 /// does not support source-based discovery). /// </summary> /// <param name="assemblyInfo">The assembly to use for discovery</param> /// <param name="projectAssembly">The test project assembly.</param> /// <param name="referenceList">The full path names of all referenced assemblies. This is used to /// search for references to specific xUnit.net reference assemblies to determine which version /// of xUnit.net the tests were written against.</param> /// <param name="sourceInformationProvider">The optional source information provider.</param> /// <param name="diagnosticMessageSink">The message sink which receives <see cref="_DiagnosticMessage"/> messages.</param> /// <returns></returns> public static IFrontControllerDiscoverer ForDiscovery( _IAssemblyInfo assemblyInfo, XunitProjectAssembly projectAssembly, IReadOnlyCollection <string> referenceList, _ISourceInformationProvider?sourceInformationProvider = null, _IMessageSink?diagnosticMessageSink = null) { Guard.ArgumentNotNull(assemblyInfo); Guard.ArgumentNotNull(projectAssembly); Guard.ArgumentNotNull(referenceList); var innerDiscoverer = default(IFrontControllerDiscoverer); var assemblyFileName = projectAssembly.AssemblyFileName; if (diagnosticMessageSink == null) { diagnosticMessageSink = _NullMessageSink.Instance; } if (sourceInformationProvider == null) { sourceInformationProvider = _NullSourceInformationProvider.Instance; #if NETFRAMEWORK if (assemblyFileName != null) { sourceInformationProvider = new VisualStudioSourceInformationProvider(assemblyFileName, diagnosticMessageSink); } #endif } var v2PathPattern = new Regex(@"^xunit\.execution\..*\.dll$"); var v2ExecutionReference = referenceList.FirstOrDefault(reference => v2PathPattern.IsMatch(Path.GetFileNameWithoutExtension(reference))); if (v2ExecutionReference != null) { innerDiscoverer = Xunit2.ForDiscovery(assemblyInfo, projectAssembly, v2ExecutionReference, sourceInformationProvider, diagnosticMessageSink); } #if NETFRAMEWORK if (referenceList.Any(reference => Path.GetFileNameWithoutExtension(reference) == "xunit.dll")) { innerDiscoverer = Xunit1.ForDiscoveryAndExecution(projectAssembly, sourceInformationProvider, diagnosticMessageSink); } #endif if (innerDiscoverer == null) { throw new InvalidOperationException($"Unknown test framework: could not find xunit.dll (v1) or xunit.execution.*.dll (v2) in assembly reference list"); } return(new XunitFrontController(innerDiscoverer)); }
/// <summary> /// Initializes a new instance of the <see cref="TestAssembly"/> class. /// </summary> /// <param name="assembly">The test assembly.</param> /// <param name="configFileName">The optional configuration filename</param> /// <param name="version">The version number of the assembly (defaults to "0.0.0.0")</param> /// <param name="uniqueID">The unique ID for the test assembly (only used to override default behavior in testing scenarios)</param> public TestAssembly( _IAssemblyInfo assembly, string?configFileName = null, Version?version = null, string?uniqueID = null) { Assembly = Guard.ArgumentNotNull(assembly); ConfigFileName = configFileName; this.uniqueID = uniqueID ?? UniqueIDGenerator.ForAssembly(assembly.Name, assembly.AssemblyPath, configFileName); Version = version ?? (assembly as _IReflectionAssemblyInfo)?.Assembly?.GetName()?.Version ?? new Version(0, 0, 0, 0); }
/// <summary> /// Gets the target framework name for the given assembly. /// </summary> /// <param name="assembly">The assembly.</param> /// <returns>The target framework (typically in a format like ".NETFramework,Version=v4.7.2" /// or ".NETCoreApp,Version=v2.1"). If the target framework type is unknown (missing file, /// missing attribute, etc.) then returns "UnknownTargetFramework".</returns> public static string GetTargetFramework(this _IAssemblyInfo assembly) { Guard.ArgumentNotNull(nameof(assembly), assembly); string?result = null; var attrib = assembly.GetCustomAttributes(typeof(TargetFrameworkAttribute)).FirstOrDefault(); if (attrib != null) { result = attrib.GetConstructorArguments().Cast <string>().First(); } return(result ?? AssemblyExtensions.UnknownTargetFramework); }
/// <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="collectionFactory">The test collection factory used to look up test collections.</param> public XunitTestFrameworkDiscoverer( _IAssemblyInfo assemblyInfo, string?configFileName, IXunitTestCollectionFactory?collectionFactory = null) : base(assemblyInfo) { var collectionBehaviorAttribute = assemblyInfo.GetCustomAttributes(typeof(CollectionBehaviorAttribute)).SingleOrDefault(); var disableParallelization = collectionBehaviorAttribute != null && collectionBehaviorAttribute.GetNamedArgument <bool>("DisableTestParallelization"); testAssembly = new TestAssembly(assemblyInfo, configFileName); TestCollectionFactory = collectionFactory ?? ExtensibilityPointFactory.GetXunitTestCollectionFactory(collectionBehaviorAttribute, testAssembly) ?? new CollectionPerClassTestCollectionFactory(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="configFileName">The test configuration file.</param> /// <param name="sourceProvider">The source information provider.</param> /// <param name="diagnosticMessageSink">The message sink which receives <see cref="_DiagnosticMessage"/> 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, configFileName, sourceProvider, diagnosticMessageSink) { var collectionBehaviorAttribute = assemblyInfo.GetCustomAttributes(typeof(CollectionBehaviorAttribute)).SingleOrDefault(); var disableParallelization = collectionBehaviorAttribute != null && collectionBehaviorAttribute.GetNamedArgument <bool>("DisableTestParallelization"); var testAssembly = new TestAssembly(assemblyInfo, configFileName); TestAssemblyUniqueID = testAssembly.UniqueID; TestCollectionFactory = collectionFactory ?? ExtensibilityPointFactory.GetXunitTestCollectionFactory(diagnosticMessageSink, collectionBehaviorAttribute, testAssembly) ?? new CollectionPerClassTestCollectionFactory(testAssembly, diagnosticMessageSink); TestFrameworkDisplayName = $"{DisplayName} [{TestCollectionFactory.DisplayName}, {(disableParallelization ? "non-parallel" : "parallel")}]"; }
/// <summary> /// Initializes a new instance of the <see cref="TestFrameworkDiscoverer{TTestCase}"/> class. /// </summary> /// <param name="assemblyInfo">The test assembly.</param> protected TestFrameworkDiscoverer(_IAssemblyInfo assemblyInfo) { this.assemblyInfo = Guard.ArgumentNotNull(assemblyInfo); targetFramework = new Lazy <string>(() => AssemblyInfo.GetTargetFramework()); }
protected TestableXunitTestFrameworkDiscoverer(_IAssemblyInfo assembly) : this(assembly, null, null, null) { }
public TestCollectionFactory_DoesNotImplementInterface(_IAssemblyInfo _) { }
public _ITestFrameworkDiscoverer GetDiscoverer(_IAssemblyInfo assembly) => throw new NotImplementedException();
/// <inheritdoc/> protected override _ITestFrameworkDiscoverer CreateDiscoverer(_IAssemblyInfo assembly) => new XunitTestFrameworkDiscoverer(assembly, configFileName, SourceInformationProvider, DiagnosticMessageSink);
Xunit2( _IMessageSink diagnosticMessageSink, AppDomainSupport appDomainSupport, _ISourceInformationProvider sourceInformationProvider, _IAssemblyInfo?assemblyInfo, string?assemblyFileName, string xunitExecutionAssemblyPath, string?configFileName, bool shadowCopy, string?shadowCopyFolder, bool verifyAssembliesOnDisk) { #if NETFRAMEWORK // Only safe to assume the execution reference is copied in a desktop project if (verifyAssembliesOnDisk) { Guard.FileExists(xunitExecutionAssemblyPath); } CanUseAppDomains = !IsDotNet(xunitExecutionAssemblyPath); #else CanUseAppDomains = false; #endif DiagnosticMessageSink = diagnosticMessageSink; var appDomainAssembly = assemblyFileName ?? xunitExecutionAssemblyPath; AppDomain = AppDomainManagerFactory.Create(appDomainSupport != AppDomainSupport.Denied && CanUseAppDomains, appDomainAssembly, configFileName, shadowCopy, shadowCopyFolder, diagnosticMessageSink); DisposalTracker.Add(AppDomain); #if NETFRAMEWORK var runnerUtilityAssemblyLocation = Path.GetDirectoryName(typeof(AssemblyHelper).Assembly.GetLocalCodeBase()); assemblyHelper = AppDomain.CreateObjectFrom <AssemblyHelper>(typeof(AssemblyHelper).Assembly.Location, typeof(AssemblyHelper).FullName !, runnerUtilityAssemblyLocation); DisposalTracker.Add(assemblyHelper); #endif TestFrameworkAssemblyName = GetTestFrameworkAssemblyName(xunitExecutionAssemblyPath); // We need both a v2 and v3 assembly info, so manufacture the things we're missing IAssemblyInfo remoteAssemblyInfo; if (assemblyInfo != null) { remoteAssemblyInfo = new Xunit2AssemblyInfo(assemblyInfo); } else { remoteAssemblyInfo = Guard.NotNull( "Could not create Xunit.Sdk.TestFrameworkProxy for v2 unit test", AppDomain.CreateObject <IAssemblyInfo>(TestFrameworkAssemblyName, "Xunit.Sdk.ReflectionAssemblyInfo", assemblyFileName) ); assemblyInfo = new Xunit3AssemblyInfo(remoteAssemblyInfo); } this.assemblyInfo = assemblyInfo; this.configFileName = configFileName; TestAssemblyUniqueID = UniqueIDGenerator.ForAssembly(this.assemblyInfo.Name, this.assemblyInfo.AssemblyPath, configFileName); var v2SourceInformationProvider = Xunit2SourceInformationProviderAdapter.Adapt(sourceInformationProvider); var v2DiagnosticMessageSink = new Xunit2MessageSink(DiagnosticMessageSink); remoteFramework = Guard.NotNull( "Could not create Xunit.Sdk.TestFrameworkProxy for v2 unit test", AppDomain.CreateObject <ITestFramework>( TestFrameworkAssemblyName, "Xunit.Sdk.TestFrameworkProxy", remoteAssemblyInfo, v2SourceInformationProvider, v2DiagnosticMessageSink ) ); DisposalTracker.Add(remoteFramework); remoteDiscoverer = Guard.NotNull("Could not get discoverer from test framework for v2 unit test", remoteFramework.GetDiscoverer(remoteAssemblyInfo)); DisposalTracker.Add(remoteDiscoverer); // If we got an assembly file name, that means we can do execution as well as discovery. if (assemblyFileName != null) { #if NETFRAMEWORK var assemblyName = AssemblyName.GetAssemblyName(assemblyFileName); #else var an = Assembly.Load(new AssemblyName { Name = Path.GetFileNameWithoutExtension(assemblyFileName) }).GetName(); var assemblyName = new AssemblyName { Name = an.Name, Version = an.Version }; #endif remoteExecutor = remoteFramework.GetExecutor(assemblyName); DisposalTracker.Add(remoteExecutor); } }
TestableTestFrameworkDiscoverer(_IAssemblyInfo assemblyInfo) : base(assemblyInfo) { TestAssembly = Mocks.TestAssembly(assemblyInfo.AssemblyPath, uniqueID: "asm-id"); }
/// <summary> /// Initializes a new instance of the <see cref="Xunit2AssemblyInfo"/> class. /// </summary> /// <param name="v3AssemblyInfo">The v3 assembly info to wrap.</param> public Xunit2AssemblyInfo(_IAssemblyInfo v3AssemblyInfo) { V3AssemblyInfo = Guard.ArgumentNotNull(v3AssemblyInfo); }
/// <inheritdoc/> protected override _ITestFrameworkDiscoverer CreateDiscoverer(_IAssemblyInfo assembly) => new XunitTestFrameworkDiscoverer(assembly, configFileName);