/// <summary>
        /// Returns an implementation of <see cref="IFrontController"/> which can be used
        /// for both discovery and execution.
        /// </summary>
        /// <param name="projectAssembly">The test project assembly.</param>
        /// <param name="sourceInformationProvider">The source information provider. If <c>null</c>, uses the default (<see cref="T:Xunit.VisualStudioSourceInformationProvider"/>).</param>
        /// <param name="diagnosticMessageSink">The message sink which receives <see cref="_DiagnosticMessage"/> messages.</param>
        public static IFrontController ForDiscoveryAndExecution(
            XunitProjectAssembly projectAssembly,
            _ISourceInformationProvider?sourceInformationProvider = null,
            _IMessageSink?diagnosticMessageSink = null)
        {
            Guard.ArgumentNotNull(nameof(projectAssembly), projectAssembly);

            var innerController  = default(IFrontController);
            var assemblyFileName = projectAssembly.AssemblyFilename;
            var assemblyFolder   = Path.GetDirectoryName(assemblyFileName);

            if (diagnosticMessageSink == null)
            {
                diagnosticMessageSink = new _NullMessageSink();
            }

#if NETFRAMEWORK
            if (sourceInformationProvider == null)
            {
                if (assemblyFileName == null)
                {
                    sourceInformationProvider = _NullSourceInformationProvider.Instance;
                }
                else
                {
                    sourceInformationProvider = new VisualStudioSourceInformationProvider(assemblyFileName, diagnosticMessageSink);
                }
            }

            if (assemblyFolder != null)
            {
                if (Directory.EnumerateFiles(assemblyFolder, "xunit.execution.*.dll").Any())
                {
                    innerController = Xunit2.ForDiscoveryAndExecution(projectAssembly, sourceInformationProvider, diagnosticMessageSink);
                }
                else
                {
                    var xunitPath = Path.Combine(assemblyFolder, "xunit.dll");
                    if (File.Exists(xunitPath))
                    {
                        innerController = Xunit1.ForDiscoveryAndExecution(projectAssembly, sourceInformationProvider, diagnosticMessageSink);
                    }
                }
            }
#else
            if (sourceInformationProvider == null)
            {
                sourceInformationProvider = _NullSourceInformationProvider.Instance;
            }

            innerController = Xunit2.ForDiscoveryAndExecution(projectAssembly, sourceInformationProvider, diagnosticMessageSink);
#endif

            if (innerController == null)
            {
                throw new InvalidOperationException($"Unknown test framework: could not find xunit.dll (v1) or xunit.execution.*.dll (v2) in {assemblyFolder ?? "<unknown assembly folder>"}");
            }

            return(new XunitFrontController(innerController));
        }
        // 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,
            IEnumerable <string> referenceList,
            _ISourceInformationProvider?sourceInformationProvider = null,
            _IMessageSink?diagnosticMessageSink = null)
        {
            Guard.ArgumentNotNull(nameof(assemblyInfo), assemblyInfo);
            Guard.ArgumentNotNull(nameof(projectAssembly), projectAssembly);
            Guard.ArgumentNotNull(nameof(referenceList), referenceList);

            var innerDiscoverer  = default(IFrontControllerDiscoverer);
            var assemblyFileName = projectAssembly.AssemblyFilename;

            if (diagnosticMessageSink == null)
            {
                diagnosticMessageSink = new _NullMessageSink();
            }

            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));
        }
Example #3
0
    public Task <List <_MessageSinkMessage> > RunAsync(Type[] types)
    {
        var tcs = new TaskCompletionSource <List <_MessageSinkMessage> >();

        ThreadPool.QueueUserWorkItem(async _ =>
        {
            try
            {
                var diagnosticMessageSink     = new _NullMessageSink();
                await using var testFramework = new XunitTestFramework(diagnosticMessageSink, configFileName: null);

                using var discoverySink = SpyMessageSink <_DiscoveryComplete> .Create();
                var assemblyInfo        = Reflector.Wrap(Assembly.GetEntryAssembly() !);
                var discoverer          = testFramework.GetDiscoverer(assemblyInfo);
                foreach (var type in types)
                {
                    discoverer.Find(type.FullName !, discoverySink, _TestFrameworkOptions.ForDiscovery());
                    discoverySink.Finished.WaitOne();
                    discoverySink.Finished.Reset();
                }

                var testCases = discoverySink.Messages.OfType <_TestCaseDiscovered>().Select(msg => msg.Serialization).ToArray();

                using var runSink = SpyMessageSink <_TestAssemblyFinished> .Create();
                var executor      = testFramework.GetExecutor(assemblyInfo);
                executor.RunTests(testCases, runSink, _TestFrameworkOptions.ForExecution());
                runSink.Finished.WaitOne();

                tcs.TrySetResult(runSink.Messages.ToList());
            }
            catch (Exception ex)
            {
                tcs.TrySetException(ex);
            }
        });

        return(tcs.Task);
    }
Example #4
0
        /// <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(nameof(member), 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).IsAssignableFrom(traitAttributeType))
                {
                    continue;
                }

                var discovererAttributeData = FindDiscovererAttributeType(traitAttributeType);
                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);
        }