Пример #1
0
        /// <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);
        }
Пример #2
0
        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));
        }
Пример #3
0
        // 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
                       ));
        }
Пример #4
0
 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() })
Пример #6
0
    /// <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));
    }
Пример #7
0
    /// <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));
    }
Пример #8
0
        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();
 }
Пример #10
0
    /// <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);
            }
        }
    }
Пример #11
0
        /// <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());
        }
Пример #12
0
        // 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));
        }
Пример #13
0
        /// <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);
        }
Пример #14
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")}]";
        }
Пример #17
0
        /// <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)
 {
 }
Пример #19
0
 public TestCollectionFactory_DoesNotImplementInterface(_IAssemblyInfo _)
 {
 }
Пример #20
0
 public _ITestFrameworkDiscoverer GetDiscoverer(_IAssemblyInfo assembly) =>
 throw new NotImplementedException();
Пример #21
0
 /// <inheritdoc/>
 protected override _ITestFrameworkDiscoverer CreateDiscoverer(_IAssemblyInfo assembly) =>
 new XunitTestFrameworkDiscoverer(assembly, configFileName, SourceInformationProvider, DiagnosticMessageSink);
Пример #22
0
        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");
 }
Пример #24
0
 /// <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);
 }
Пример #25
0
 /// <inheritdoc/>
 protected override _ITestFrameworkDiscoverer CreateDiscoverer(_IAssemblyInfo assembly) =>
 new XunitTestFrameworkDiscoverer(assembly, configFileName);