Example #1
0
        public TdNetRunnerHelper(Assembly assembly, ITestListener testListener)
        {
            this.testListener = testListener;

            xunit = new Xunit2(new NullSourceInformationProvider(), assembly.GetLocalCodeBase());
            toDispose.Push(xunit);
        }
Example #2
0
        public TdNetRunnerHelper(Assembly assembly, ITestListener testListener)
        {
            this.testListener = testListener;

            xunit = new Xunit2(new NullSourceInformationProvider(), assembly.GetLocalCodeBase());
            toDispose.Push(xunit);
        }
Example #3
0
        public TdNetRunnerHelper(Assembly assembly, ITestListener testListener)
        {
            this.testListener = testListener;

            var assemblyFileName = assembly.GetLocalCodeBase();

            xunit         = new Xunit2(new NullSourceInformationProvider(), assemblyFileName);
            configuration = ConfigReader.Load(assemblyFileName);
            toDispose.Push(xunit);
        }
Example #4
0
        private Xunit2 InternRunner(Assembly assembly)
        {
            if (!this.runners.TryGetValue(assembly, out var runner))
            {
                runner = new Xunit2(AppDomainSupport.Denied, new NullSourceInformationProvider(), assembly.GetFileName());
                this.runners.Add(assembly, runner);
            }

            return(runner);
        }
        public TdNetRunnerHelper(Assembly assembly, ITestListener testListener)
        {
            this.testListener = testListener;

            var assemblyFileName = assembly.GetLocalCodeBase();
            configuration = ConfigReader.Load(assemblyFileName);
            var diagnosticMessageSink = new DiagnosticMessageSink(testListener, Path.GetFileNameWithoutExtension(assemblyFileName), configuration.DiagnosticMessagesOrDefault);
            xunit = new Xunit2(configuration.AppDomainOrDefault, new NullSourceInformationProvider(), assemblyFileName, shadowCopy: false, diagnosticMessageSink: diagnosticMessageSink);
            toDispose.Push(xunit);
        }
Example #6
0
        public static IEnumerable <IMessageSinkMessage> Run(this Xunit2 runner, IEnumerable <ITestCase> testCases)
        {
            Guard.AgainstNullArgument("runner", runner);

            using (var sink = new SpyMessageSink <ITestAssemblyFinished>())
            {
                runner.RunTests(testCases, sink, TestFrameworkOptions.ForExecution());
                sink.Finished.WaitOne();
                return(sink.Messages.Select(message => message));
            }
        }
Example #7
0
        private static void ExecuteTests(string code, Action <MessageSink> assertions)
        {
            var assemblyName = TestAssemblyCompiler.Compile(code);
            var sink         = new MessageSink();

            using (var xunit2 = new Xunit2(new NullSourceInformationProvider(), assemblyName, null, false))
            {
                xunit2.RunAll(sink, TestFrameworkOptions.ForDiscovery(), TestFrameworkOptions.ForExecution());
                sink.WaitTillFinished();
                assertions(sink);
            }
        }
Example #8
0
        public TdNetRunnerHelper(Assembly assembly, ITestListener testListener)
        {
            this.testListener = testListener;

            var assemblyFileName = assembly.GetLocalCodeBase();

            configuration = ConfigReader.Load(assemblyFileName);
            var diagnosticMessageVisitor = new DiagnosticMessageVisitor(testListener, Path.GetFileNameWithoutExtension(assemblyFileName), configuration.DiagnosticMessagesOrDefault);

            xunit = new Xunit2(configuration.UseAppDomainOrDefault, new NullSourceInformationProvider(), assemblyFileName, shadowCopy: false, diagnosticMessageSink: diagnosticMessageVisitor);
            toDispose.Push(xunit);
        }
Example #9
0
        public void DiscoverTests(IEnumerable<string> sources, IDiscoveryContext discoveryContext, IMessageLogger logger, ITestCaseDiscoverySink discoverySink)
        {
            Guard.ArgumentNotNull("sources", sources);
            Guard.ArgumentNotNull("logger", logger);
            Guard.ArgumentNotNull("discoverySink", discoverySink);

            try
            {
                RemotingUtility.CleanUpRegisteredChannels();
                List<SourceSink> sourceSinks = new List<SourceSink>();

                using (AssemblyHelper.SubscribeResolve())
                    try
                    {
                        foreach (string source in sources)
                        {
                            try
                            {
                                if (cancelled)
                                    break;

                                if (IsXunitTestAssembly(source))
                                {
                                    var framework = new Xunit2(SourceInformationProvider, source, configFileName: null, shadowCopy: true);
                                    var sink = new VsDiscoveryVisitor(source, framework, logger, discoverySink, () => cancelled);
                                    sourceSinks.Add(new SourceSink { Framework = framework, Source = source, Sink = sink });
                                    framework.Find(includeSourceInformation: true, messageSink: sink);
                                }
                            }
                            catch (Exception e)
                            {
                                logger.SendMessage(TestMessageLevel.Error, String.Format("xUnit.net: Exception discovering tests from {0}: {1}", source, e));
                            }

                        }

                        foreach (var sourceSink in sourceSinks)
                            sourceSink.Sink.Finished.WaitOne();
                    }
                    finally
                    {
                        foreach (var sourceSink in sourceSinks)
                        {
                            sourceSink.Sink.Dispose();
                            sourceSink.Framework.Dispose();
                        }
                    }
            }
            catch
            {
            }
        }
Example #10
0
        public static Queue <IMessageSinkMessage> Run(this Xunit2 runner, Queue <ITestCase> testCases, TestAssemblyConfiguration testAssemblyConfiguration)
        {
            if (!testCases.Any())
            {
                return(new Queue <IMessageSinkMessage>());
            }

            using (var sink = new SpyMessageSink <ITestCollectionFinished>())
            {
                runner.RunTests(testCases, sink, TestFrameworkOptions.ForExecution(testAssemblyConfiguration));
                sink.Finished.Wait();
                return(sink.Messages);
            }
        }
        public static IEnumerable <IMessageSinkMessage> Run(this Xunit2 runner, IEnumerable <ITestCase> testCases)
        {
            if (!testCases.Any())
            {
                return(Enumerable.Empty <IMessageSinkMessage>());
            }

            using (var sink = new SpyMessageSink <ITestCollectionFinished>())
            {
                runner.RunTests(testCases, sink, TestFrameworkOptions.ForExecution());
                sink.Finished.WaitOne();
                return(sink.Messages.Select(_ => _));
            }
        }
Example #12
0
    public List <IMessageSinkMessage> Run(Type[] types, Func <IMessageSinkMessage, bool> cancellationThunk = null)
    {
        Xunit2 = new Xunit2(new NullSourceInformationProvider(), new Uri(types[0].Assembly.CodeBase).LocalPath, configFileName: null, shadowCopy: true);

        bool cancelled = false;
        Func <IMessageSinkMessage, bool> wrapper = msg =>
        {
            var result = true;

            if (cancellationThunk != null)
            {
                result = cancellationThunk(msg);
            }

            if (!result)
            {
                cancelled = true;
            }

            return(result);
        };

        var discoverySink = new SpyMessageSink <IDiscoveryCompleteMessage>(wrapper);

        foreach (Type type in types)
        {
            Xunit2.Find(type.FullName, includeSourceInformation: false, messageSink: discoverySink);
            discoverySink.Finished.WaitOne();
            discoverySink.Finished.Reset();
        }

        if (cancelled)
        {
            return(new List <IMessageSinkMessage>());
        }

        var testCases = discoverySink.Messages.OfType <ITestCaseDiscoveryMessage>().Select(msg => msg.TestCase).ToArray();

        var runSink = new SpyMessageSink <ITestAssemblyFinished>(cancellationThunk);

        Xunit2.Run(testCases, runSink);
        runSink.Finished.WaitOne();

        return(runSink.Messages.ToList());
    }
Example #13
0
        private bool RunTestAssembly(TestOptions options, string testTarget, IAssemblyLoaderContainer container, IServiceProvider services)
        {
            bool success = true;

            testTarget = Path.GetFullPath(testTarget);
            var applicationDir  = Directory.Exists(testTarget) ? testTarget : Path.GetDirectoryName(testTarget);
            var applicationName = Directory.Exists(testTarget) ? Path.GetFileName(testTarget) : Path.GetFileNameWithoutExtension(testTarget);

            var hostOptions = new DefaultHostOptions
            {
                WatchFiles               = false,
                PackageDirectory         = options.PackageDirectory,
                TargetFramework          = _environment.RuntimeFramework,
                Configuration            = options.Configuration,
                ApplicationBaseDirectory = applicationDir,
                CompilationServerPort    = options.CompilationServerPort
            };

            using (var host = new DefaultHost(hostOptions, services))
                using (host.AddLoaders(container))
                {
                    host.Initialize();
                    var libraryManager = (ILibraryManager)host.ServiceProvider.GetService(typeof(ILibraryManager));
                    var assemblies     = libraryManager.GetLibraryInformation(applicationName).LoadableAssemblies.Select(Assembly.Load);

                    foreach (var assembly in assemblies)
                    {
                        using (var framework = new Xunit2(new NullSourceInformationProvider(), assembly.GetName().Name))
                        {
                            switch (options.RunKind)
                            {
                            case RunKind.List:
                                DiscoverTests(options, framework, services);
                                break;

                            default:
                                success = RunTests(options, framework, services) && success;
                                break;
                            }
                        }
                    }
                }

            return(success);
        }
        public static IFrontController Create(
            string assemblyFileName,
            string?configFileName             = null,
            bool shadowCopy                   = true,
            AppDomainSupport appDomainSupport = AppDomainSupport.Required)
        {
            var project         = new XunitProject();
            var projectAssembly = new XunitProjectAssembly(project)
            {
                AssemblyFilename = assemblyFileName,
                ConfigFilename   = configFileName,
            };

            projectAssembly.Configuration.AppDomain  = appDomainSupport;
            projectAssembly.Configuration.ShadowCopy = shadowCopy;

            return(Xunit2.ForDiscoveryAndExecution(projectAssembly, diagnosticMessageSink: new _NullMessageSink()));
        }
Example #15
0
    public List <IMessageSinkMessage> Run(Type[] types)
    {
        Xunit2 = new Xunit2(AppDomainSupport.Required, new NullSourceInformationProvider(), types[0].Assembly.GetLocalCodeBase(), configFileName: null, shadowCopy: true);

        var discoverySink = new SpyMessageSink <IDiscoveryCompleteMessage>();

        foreach (var type in types)
        {
            Xunit2.Find(type.FullName, includeSourceInformation: false, messageSink: discoverySink, discoveryOptions: TestFrameworkOptions.ForDiscovery());
            discoverySink.Finished.WaitOne();
            discoverySink.Finished.Reset();
        }

        var testCases = discoverySink.Messages.OfType <ITestCaseDiscoveryMessage>().Select(msg => msg.TestCase).ToArray();

        var runSink = new SpyMessageSink <ITestAssemblyFinished>();

        Xunit2.RunTests(testCases, runSink, TestFrameworkOptions.ForExecution());
        runSink.Finished.WaitOne();

        return(runSink.Messages.ToList());
    }
Example #16
0
        public TdNetRunnerHelper(
            Assembly assembly,
            ITestListener testListener)
        {
            this.testListener = testListener;

            var assemblyFileName = assembly.GetLocalCodeBase();
            var project          = new XunitProject();

            projectAssembly = new XunitProjectAssembly(project)
            {
                Assembly         = assembly,
                AssemblyFilename = assemblyFileName,
                TargetFramework  = AssemblyUtility.GetTargetFramework(assemblyFileName)
            };
            projectAssembly.Configuration.ShadowCopy = false;
            ConfigReader.Load(projectAssembly.Configuration, assemblyFileName);

            var diagnosticMessageSink = new DiagnosticMessageSink(testListener, Path.GetFileNameWithoutExtension(assemblyFileName), projectAssembly.Configuration.DiagnosticMessagesOrDefault);

            frontController = Xunit2.ForDiscoveryAndExecution(projectAssembly, diagnosticMessageSink: diagnosticMessageSink);
            disposalTracker.Add(frontController);
        }
        public int Run(string assemblyFileName, bool printXml, XunitFilters filters)
        {
            var configuration = new TestAssemblyConfiguration()
            {
                ShadowCopy = false, ParallelizeAssembly = false, ParallelizeTestCollections = false, MaxParallelThreads = 1, PreEnumerateTheories = false
            };
            var discoveryOptions = TestFrameworkOptions.ForDiscovery(configuration);
            var discoverySink    = new TestDiscoverySink();
            var diagnosticSink   = new ConsoleDiagnosticMessageSink();
            var testOptions      = TestFrameworkOptions.ForExecution(configuration);
            var testSink         = new TestMessageSink();
            var controller       = new Xunit2(AppDomainSupport.Denied, new NullSourceInformationProvider(), assemblyFileName, configFileName: null, shadowCopy: false, shadowCopyFolder: null, diagnosticMessageSink: diagnosticSink, verifyTestAssemblyExists: false);

            discoveryOptions.SetSynchronousMessageReporting(true);
            testOptions.SetSynchronousMessageReporting(true);

            Console.WriteLine($"Discovering tests for {assemblyFileName}");
            var assembly     = Assembly.LoadFrom(assemblyFileName);
            var assemblyInfo = new global::Xunit.Sdk.ReflectionAssemblyInfo(assembly);
            var discoverer   = new ThreadlessXunitDiscoverer(assemblyInfo, new NullSourceInformationProvider(), discoverySink);

            discoverer.FindWithoutThreads(includeSourceInformation: false, discoverySink, discoveryOptions);
            discoverySink.Finished.WaitOne();
            var testCasesToRun = discoverySink.TestCases.Where(filters.Filter).ToList();

            Console.WriteLine($"Discovery finished.");

            var summarySink        = new DelegatingExecutionSummarySink(testSink, () => false, (completed, summary) => { Console.WriteLine($"Tests run: {summary.Total}, Errors: 0, Failures: {summary.Failed}, Skipped: {summary.Skipped}. Time: {TimeSpan.FromSeconds((double)summary.Time).TotalSeconds}s"); });
            var resultsXmlAssembly = new XElement("assembly");
            var resultsSink        = new DelegatingXmlCreationSink(summarySink, resultsXmlAssembly);

            testSink.Execution.TestPassedEvent  += args => { Console.WriteLine($"[PASS] {args.Message.Test.DisplayName}"); };
            testSink.Execution.TestSkippedEvent += args => { Console.WriteLine($"[SKIP] {args.Message.Test.DisplayName}"); };
            testSink.Execution.TestFailedEvent  += args => { Console.WriteLine($"[FAIL] {args.Message.Test.DisplayName}{Environment.NewLine}{ExceptionUtility.CombineMessages(args.Message)}{Environment.NewLine}{ExceptionUtility.CombineStackTraces(args.Message)}"); };

            testSink.Execution.TestAssemblyStartingEvent += args => { Console.WriteLine($"Running tests for {args.Message.TestAssembly.Assembly}"); };
            testSink.Execution.TestAssemblyFinishedEvent += args => { Console.WriteLine($"Finished {args.Message.TestAssembly.Assembly}{Environment.NewLine}"); };

            controller.RunTests(testCasesToRun, resultsSink, testOptions);
            var threadpoolPump = typeof(ThreadPool).GetMethod("PumpThreadPool", BindingFlags.NonPublic | BindingFlags.Static);

            if (threadpoolPump != null)
            {
                while (!resultsSink.Finished.WaitOne(0))
                {
                    threadpoolPump.Invoke(this, null);
                }
            }
            else
            {
                resultsSink.Finished.WaitOne();
            }

            if (printXml)
            {
                Console.WriteLine($"STARTRESULTXML");
                var resultsXml = new XElement("assemblies");
                resultsXml.Add(resultsXmlAssembly);
                resultsXml.Save(Console.OpenStandardOutput());
                Console.WriteLine();
                Console.WriteLine($"ENDRESULTXML");
            }

            var failed = resultsSink.ExecutionSummary.Failed > 0 || resultsSink.ExecutionSummary.Errors > 0;

            return(failed ? 1 : 0);
        }
Example #18
0
        public async Task <int> Run(string assemblyFileName, bool printXml, XunitFilters filters)
        {
            var configuration = new TestAssemblyConfiguration()
            {
                ShadowCopy = false, ParallelizeAssembly = false, ParallelizeTestCollections = false, MaxParallelThreads = 1, PreEnumerateTheories = false
            };
            var discoveryOptions = TestFrameworkOptions.ForDiscovery(configuration);
            var discoverySink    = new TestDiscoverySink();
            var diagnosticSink   = new ConsoleDiagnosticMessageSink();
            var testOptions      = TestFrameworkOptions.ForExecution(configuration);
            var testSink         = new TestMessageSink();
            var controller       = new Xunit2(AppDomainSupport.Denied, new NullSourceInformationProvider(), assemblyFileName, configFileName: null, shadowCopy: false, shadowCopyFolder: null, diagnosticMessageSink: diagnosticSink, verifyTestAssemblyExists: false);

            discoveryOptions.SetSynchronousMessageReporting(true);
            testOptions.SetSynchronousMessageReporting(true);

            Console.WriteLine($"Discovering: {assemblyFileName} (method display = {discoveryOptions.GetMethodDisplayOrDefault()}, method display options = {discoveryOptions.GetMethodDisplayOptionsOrDefault()})");
            var assembly     = Assembly.LoadFrom(assemblyFileName);
            var assemblyInfo = new global::Xunit.Sdk.ReflectionAssemblyInfo(assembly);
            var discoverer   = new ThreadlessXunitDiscoverer(assemblyInfo, new NullSourceInformationProvider(), discoverySink);

            discoverer.FindWithoutThreads(includeSourceInformation: false, discoverySink, discoveryOptions);
            discoverySink.Finished.WaitOne();
            var testCasesToRun = discoverySink.TestCases.Where(filters.Filter).ToList();

            Console.WriteLine($"Discovered:  {assemblyFileName} (found {testCasesToRun.Count} of {discoverySink.TestCases.Count} test cases)");

            var summarySink        = new DelegatingExecutionSummarySink(testSink, () => false, (completed, summary) => { Console.WriteLine($"{Environment.NewLine}=== TEST EXECUTION SUMMARY ==={Environment.NewLine}Total: {summary.Total}, Errors: 0, Failed: {summary.Failed}, Skipped: {summary.Skipped}, Time: {TimeSpan.FromSeconds((double)summary.Time).TotalSeconds}s{Environment.NewLine}"); });
            var resultsXmlAssembly = new XElement("assembly");
            var resultsSink        = new DelegatingXmlCreationSink(summarySink, resultsXmlAssembly);

            if (Environment.GetEnvironmentVariable("XHARNESS_LOG_TEST_START") != null)
            {
                testSink.Execution.TestStartingEvent += args => { Console.WriteLine($"[STRT] {args.Message.Test.DisplayName}"); };
            }
            testSink.Execution.TestPassedEvent  += args => { Console.WriteLine($"[PASS] {args.Message.Test.DisplayName}"); };
            testSink.Execution.TestSkippedEvent += args => { Console.WriteLine($"[SKIP] {args.Message.Test.DisplayName}"); };
            testSink.Execution.TestFailedEvent  += args => { Console.WriteLine($"[FAIL] {args.Message.Test.DisplayName}{Environment.NewLine}{ExceptionUtility.CombineMessages(args.Message)}{Environment.NewLine}{ExceptionUtility.CombineStackTraces(args.Message)}"); };

            testSink.Execution.TestAssemblyStartingEvent += args => { Console.WriteLine($"Starting:    {assemblyFileName}"); };
            testSink.Execution.TestAssemblyFinishedEvent += args => { Console.WriteLine($"Finished:    {assemblyFileName}"); };

            controller.RunTests(testCasesToRun, resultsSink, testOptions);

            while (!resultsSink.Finished.WaitOne(0))
            {
                await Task.Delay(1);
            }

            if (printXml)
            {
                Console.WriteLine($"STARTRESULTXML");
                var resultsXml = new XElement("assemblies");
                resultsXml.Add(resultsXmlAssembly);
                resultsXml.Save(Console.OpenStandardOutput());
                Console.WriteLine();
                Console.WriteLine($"ENDRESULTXML");
            }

            var failed = resultsSink.ExecutionSummary.Failed > 0 || resultsSink.ExecutionSummary.Errors > 0;

            return(failed ? 1 : 0);
        }
    public static void DeserializedFactsAndTheoriesFromTheSameClassStillShareFixtures()
    {
        var code = @"
using System;
using System.Threading;
using Xunit;

public class TestClassFixture : IDisposable
{
    public static long StaticConstructorCount = 0;
    public readonly long ConstructorInstance;

    public TestClassFixture() { ConstructorInstance = Interlocked.Increment(ref StaticConstructorCount); }

    public void Dispose() { Assert.Equal(1, StaticConstructorCount); }
}

public class TestClass : IClassFixture<TestClassFixture>
{
    readonly TestClassFixture fixture;

    public TestClass(TestClassFixture fixture) { this.fixture = fixture; }

    [Fact]
    public void FactMethod() { Assert.Equal(1, fixture.ConstructorInstance); }

    [Theory]
    [InlineData(42)]
    public void TheoryMethod(int x) { Assert.Equal(1, fixture.ConstructorInstance); }
}
";

        using (var assembly = CSharpAcceptanceTestV2Assembly.Create(code))
        {
            var discoverySink       = new SpyMessageSink <IDiscoveryCompleteMessage>();
            var serializedTestCases = default(List <string>);
            var descriptors         = default(List <TestCaseDescriptor>);

            using (var xunit2 = new Xunit2(AppDomainSupport.Required, new NullSourceInformationProvider(), assembly.FileName))
            {
                xunit2.Find("TestClass", false, discoverySink, TestFrameworkOptions.ForDiscovery());
                discoverySink.Finished.WaitOne();

                var testCases = discoverySink.Messages
                                .OfType <ITestCaseDiscoveryMessage>()
                                .Select(x => x.TestCase)
                                .ToList();

                serializedTestCases = testCases.Select(x => xunit2.Serialize(x)).ToList();
                descriptors         = xunit2.GetTestCaseDescriptors(testCases, true);
            }

            using (var xunit2 = new Xunit2(AppDomainSupport.Required, new NullSourceInformationProvider(), assembly.FileName))
            {
                var deserializations = default(List <ITestCase>);
                Action <List <KeyValuePair <string, ITestCase> > > callback = r => deserializations = r.Select(x => x.Value).ToList();

                new TestCaseBulkDeserializer(xunit2, xunit2, serializedTestCases, callback);

                var executionSink = new SpyMessageSink <ITestAssemblyFinished>();
                xunit2.RunTests(deserializations, executionSink, TestFrameworkOptions.ForExecution());
                executionSink.Finished.WaitOne();

                var passedTests = executionSink.Messages.OfType <ITestPassed>().ToList();
                var failedTests = executionSink.Messages.OfType <ITestFailed>().ToList();

                Assert.Equal(2, passedTests.Count);
                Assert.Empty(failedTests);
            }
        }
    }
Example #20
0
        void RunTestsInAssembly(IFrameworkHandle frameworkHandle, List<IDisposable> toDispose, string assemblyFileName, IEnumerable<TestCase> testCases = null)
        {
            if (cancelled)
                return;

            var xunit2 = new Xunit2(SourceInformationProvider, assemblyFileName, configFileName: null, shadowCopy: true);
            toDispose.Add(xunit2);

            if (testCases == null)
            {
                using (var visitor = new TestDiscoveryVisitor())
                {
                    xunit2.Find(includeSourceInformation: true, messageSink: visitor);
                    visitor.Finished.WaitOne();
                    testCases = visitor.TestCases.Select(tc => VsDiscoveryVisitor.CreateVsTestCase(frameworkHandle, assemblyFileName, xunit2, tc)).ToList();
                }
            }

            var xunitTestCases = testCases.ToDictionary(tc => xunit2.Deserialize(tc.GetPropertyValue<string>(SerializedTestCaseProperty, null)));

            using (var executionVisitor = new VsExecutionVisitor(assemblyFileName, frameworkHandle, xunitTestCases, () => cancelled))
            {
                xunit2.Run(xunitTestCases.Keys.ToList(), executionVisitor);
                executionVisitor.Finished.WaitOne();
            }
        }
Example #21
0
        public bool Run(string assemblyFileName, IEnumerable <string> excludedTraits)
        {
            WebAssembly.Runtime.InvokeJS($"if (document) document.body.innerHTML = ''");

            Log("Starting tests...");

            var filters = new XunitFilters();

            foreach (var trait in excludedTraits ?? Array.Empty <string>())
            {
                ParseEqualSeparatedArgument(filters.ExcludedTraits, trait);
            }

            var configuration = new TestAssemblyConfiguration
            {
                ShadowCopy                 = false,
                ParallelizeAssembly        = false,
                ParallelizeTestCollections = false,
                MaxParallelThreads         = 1,
                PreEnumerateTheories       = false
            };
            var discoveryOptions = TestFrameworkOptions.ForDiscovery(configuration);
            var discoverySink    = new TestDiscoverySink();
            var diagnosticSink   = new ConsoleDiagnosticMessageSink();
            var testOptions      = TestFrameworkOptions.ForExecution(configuration);
            var testSink         = new TestMessageSink();
            var controller       = new Xunit2(
                AppDomainSupport.Denied,
                new NullSourceInformationProvider(),
                assemblyFileName,
                configFileName: null,
                shadowCopy: false,
                shadowCopyFolder: null,
                diagnosticMessageSink: diagnosticSink,
                verifyTestAssemblyExists: false);

            discoveryOptions.SetSynchronousMessageReporting(true);
            testOptions.SetSynchronousMessageReporting(true);

            Log($"Discovering tests for {assemblyFileName}...");
            var assembly     = Assembly.LoadFrom(assemblyFileName);
            var assemblyInfo = new Xunit.Sdk.ReflectionAssemblyInfo(assembly);
            var discoverer   = new ThreadlessXunitDiscoverer(assemblyInfo, new NullSourceInformationProvider(), discoverySink);

            discoverer.FindWithoutThreads(includeSourceInformation: false, discoverySink, discoveryOptions);
            discoverySink.Finished.WaitOne();
            var testCasesToRun = discoverySink.TestCases.Where(filters.Filter).ToList();

            Log($"Discovery finished.");
            Log("");

            var summarySink = new DelegatingExecutionSummarySink(
                testSink,
                () => false,
                (completed, summary) => { Log($"Tests run: {summary.Total}, Errors: 0, Failures: {summary.Failed}, Skipped: {summary.Skipped}. Time: {TimeSpan.FromSeconds((double)summary.Time).TotalSeconds}s"); });

            var resultsXmlAssembly = new XElement("assembly");
            var resultsSink        = new DelegatingXmlCreationSink(summarySink, resultsXmlAssembly);

            testSink.Execution.TestPassedEvent  += args => { Log($"[PASS] {args.Message.Test.DisplayName}", color: "green"); };
            testSink.Execution.TestSkippedEvent += args => { Log($"[SKIP] {args.Message.Test.DisplayName}", color: "orange"); };
            testSink.Execution.TestFailedEvent  += args => { Log($"[FAIL] {args.Message.Test.DisplayName}{Environment.NewLine}{ExceptionUtility.CombineMessages(args.Message)}{Environment.NewLine}{ExceptionUtility.CombineStackTraces(args.Message)}", color: "red"); };

            testSink.Execution.TestAssemblyStartingEvent += args => { Log($"Running tests for {args.Message.TestAssembly.Assembly}"); };
            testSink.Execution.TestAssemblyFinishedEvent += args => { Log($"Finished {args.Message.TestAssembly.Assembly}{Environment.NewLine}"); };

            controller.RunTests(testCasesToRun, resultsSink, testOptions);
            resultsSink.Finished.WaitOne();

            var resultsXml = new XElement("assemblies");

            resultsXml.Add(resultsXmlAssembly);

            Console.WriteLine(resultsXml.ToString());

            Log("");
            Log("Test results (Base64 encoded):");
            var base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(resultsXml.ToString()));

            Log(base64, id: "results");

            return(resultsSink.ExecutionSummary.Failed > 0 || resultsSink.ExecutionSummary.Errors > 0);
        }