/// <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(projectAssembly);

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

            if (diagnosticMessageSink == null)
            {
                diagnosticMessageSink = _NullMessageSink.Instance;
            }

#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));
        }
Exemple #2
0
        public void FactAcceptanceTest()
        {
            string code = @"
                using System;
                using Xunit;

                namespace Namespace1
                {
                    public class Class1
                    {
                        [Fact]
                        [Trait(""Name!"", ""Value!"")]
                        public void Trait() { }

                        [Fact(Skip=""Skipping"")]
                        public void Skipped() { }

                        [Fact(DisplayName=""Custom Test Name"")]
                        public void CustomName() { }
                    }
                }

                namespace Namespace2
                {
                    public class OuterClass
                    {
                        public class Class2
                        {
                            [Fact]
                            public void TestMethod() { }
                        }
                    }
                }
            ";

            using (var assembly = new AcceptanceTestAssembly(code))
            using (var controller = new Xunit2(assembly.FileName, null, true))
            {
                var sink = new SpyMessageSink<IDiscoveryCompleteMessage>();

                controller.Find(includeSourceInformation: false, messageSink: sink);

                sink.Finished.WaitOne();
                ITestCase[] testCases = sink.Messages.OfType<ITestCaseDiscoveryMessage>().Select(tcdm => tcdm.TestCase).ToArray();

                Assert.Equal(4, testCases.Length);

                ITestCase traitTest = Assert.Single(testCases, tc => tc.DisplayName == "Namespace1.Class1.Trait");
                KeyValuePair<string, string> kvp = Assert.Single(traitTest.Traits);
                Assert.Equal("Name!", kvp.Key);
                Assert.Equal("Value!", kvp.Value);

                ITestCase skipped = Assert.Single(testCases, tc => tc.DisplayName == "Namespace1.Class1.Skipped");
                Assert.Equal("Skipping", skipped.SkipReason);

                Assert.Single(testCases, tc => tc.DisplayName == "Custom Test Name");
                Assert.Single(testCases, tc => tc.DisplayName == "Namespace2.OuterClass+Class2.TestMethod");
            }
        }
        // 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));
        }
Exemple #4
0
        public void NoTestMethods()
        {
            using (var assm = new AcceptanceTestAssembly(code: ""))
            using (var controller = new Xunit2(assm.FileName, null, true))
            {
                var sink = new SpyMessageSink<IDiscoveryCompleteMessage>();

                controller.Find(includeSourceInformation: false, messageSink: sink);

                sink.Finished.WaitOne();

                Assert.False(sink.Messages.Any(msg => msg is ITestCaseDiscoveryMessage));
            }
        }
Exemple #5
0
        public void TheoryWithInlineData()
        {
            string code = @"
                using System;
                using Xunit;

                public class TestClass
                {
                    [Theory]
                    [InlineData]
                    [InlineData(42)]
                    [InlineData(42, 21.12)]
                    public void TestMethod(int x) { }
                }
            ";

            using (var assembly = new AcceptanceTestAssembly(code))
            using (var controller = new Xunit2(assembly.FileName, null, true))
            {
                var sink = new SpyMessageSink<IDiscoveryCompleteMessage>();

                controller.Find(includeSourceInformation: false, messageSink: sink);

                sink.Finished.WaitOne();
                string[] testCaseNames = sink.Messages.OfType<ITestCaseDiscoveryMessage>().Select(tcdm => tcdm.TestCase.DisplayName).ToArray();

                Assert.Equal(3, testCaseNames.Length);

                Assert.Contains("TestClass.TestMethod(x: ???)", testCaseNames);
                Assert.Contains("TestClass.TestMethod(x: 42)", testCaseNames);
                Assert.Contains("TestClass.TestMethod(x: 42, ???: 21.12)", testCaseNames);
            }
        }
Exemple #6
0
        public void SingleTestMethod()
        {
            string code = @"
                using Xunit;

                public class Foo
                {
                    [Fact]
                    public void Bar() { }
                }
            ";

            using (var assm = new AcceptanceTestAssembly(code))
            using (var controller = new Xunit2(assm.FileName, null, true))
            {
                var sink = new SpyMessageSink<IDiscoveryCompleteMessage>();

                controller.Find(includeSourceInformation: false, messageSink: sink);

                sink.Finished.WaitOne();

                ITestCase testCase = sink.Messages.OfType<ITestCaseDiscoveryMessage>().Single().TestCase;
                Assert.Equal("Foo.Bar", testCase.DisplayName);
            }
        }
Exemple #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="XunitFrontController"/> class.
 /// </summary>
 /// <param name="assemblyFileName">The test assembly.</param>
 /// <param name="configFileName">The test assembly configuration file.</param>
 /// <param name="shadowCopy">If set to <c>true</c>, runs tests in a shadow copied app domain, which allows
 /// tests to be discovered and run without locking assembly files on disk.</param>
 public XunitFrontController(string assemblyFileName, string configFileName = null, bool shadowCopy = true)
 {
     xunit2 = new Xunit2(assemblyFileName, configFileName, shadowCopy);
 }