public void Run(XunitTestAssemblyTask assemblyTask, TaskProvider taskProvider) { var priorCurrentDirectory = Environment.CurrentDirectory; try { // Use the assembly in the folder that the user has specified, or, if not, use the assembly location var assemblyFolder = GetAssemblyFolder(configuration, assemblyTask); var assemblyPath = Path.Combine(assemblyFolder, GetFileName(assemblyTask.AssemblyLocation)); Environment.CurrentDirectory = assemblyFolder; // If we just pass null for the config file, the AppDomain will load {assembly}.config if it exists, // or use the config file of this app domain, which will usually be JetBrains.ReSharper.TaskRunner.*.exe.config. // If we specify the name directly, it will just use it, or have no configuration, with no fallback. // This is good because it stops the TaskRunner.exe config leaking into your tests. For example, that // file redirects all ReSharper assemblies to the current version. When the default AppDomain loads our // code, the assemblies are successfully redirected, and we use the latest version. If the new AppDomain // uses the same redirects, and the test assembly references resharper assemblies (e.g. xunitcontrib tests!) // the redirects are applied, but the new AppDomain can't find the newer assemblies, and throws var configFile = assemblyPath + ".config"; using (var executorWrapper = new ExecutorWrapper(assemblyPath, configFile, configuration.ShadowCopy)) { SetTempFolderPath(executorWrapper); var run = new XunitTestRun(server, executorWrapper, taskProvider); run.RunTests(); } } finally { Environment.CurrentDirectory = priorCurrentDirectory; } }
public void AssemblyWithMultipleTestsAndMultipleClasses() { string code = @" using Xunit; public class JustAPlainOldClass { public class Class1 { [Fact] public void Test1() {} [Fact] public void Test2() {} } public class Class2 { [Fact] public void Test3() {} } }"; using (MockAssembly assembly = new MockAssembly()) { assembly.Compile(code); using (ExecutorWrapper wrapper = new ExecutorWrapper(assembly.FileName, null, false)) Assert.Equal(3, wrapper.GetAssemblyTestCount()); } }
TestRunState ITdNetTestRunner.RunNamespace(ITestListener listener, Assembly assembly, string ns) { try { using (ExecutorWrapper wrapper = new ExecutorWrapper(new Uri(assembly.CodeBase).LocalPath, null, false)) { TdNetLogger logger = new TdNetLogger(listener, assembly); TestRunner runner = new TestRunner(wrapper, logger); TestRunState runState = TestRunState.NoTests; foreach (Type type in assembly.GetExportedTypes()) { if (ns == null || type.Namespace == ns) { runState = TestResultMapper.Merge(runState, RunClass(runner, type)); } } return(runState); } } catch (ArgumentException) { return(TestRunState.NoTests); } }
public void AcceptanceTest() { string code = @" using Xunit; public class TestClass { [Fact] public void TestMethod() { } }"; using (MockAssembly assembly = new MockAssembly()) { assembly.Compile(code); XmlNode lastNode = null; XmlNode returnValue = null; using (ExecutorWrapper wrapper = new ExecutorWrapper(assembly.FileName, null, false)) returnValue = wrapper.RunTest("TestClass", "TestMethod", node => { lastNode = node; return(true); }); XmlNode resultNode = ResultXmlUtility.GetResult(lastNode); Assert.Equal("Pass", resultNode.Attributes["result"].Value); Assert.Equal(returnValue, lastNode); } }
public void CanCancelBetweenTestMethodRuns() { string code = @" using Xunit; public class TestClass { [Fact] public void TestMethod1() { } [Fact] public void TestMethod2() { } }"; using (MockAssembly assembly = new MockAssembly()) { assembly.Compile(code); XmlNode lastNode = null; using (ExecutorWrapper wrapper = new ExecutorWrapper(assembly.FileName, null, false)) wrapper.RunClass("TestClass", node => { lastNode = node; return(false); }); Assert.Equal(0, lastNode.ChildNodes.Count); // Cancels from the start of the first test } }
public void AcceptanceTest() { string code = @" using Xunit; public class TestClass { [Fact] public void TestMethod1() {} [Fact] public void TestMethod2() {} [Fact] public void TestMethod3() {} }"; using (MockAssembly assembly = new MockAssembly()) { assembly.Compile(code); XmlNode lastNode = null; XmlNode returnValue = null; using (ExecutorWrapper wrapper = new ExecutorWrapper(assembly.FileName, null, false)) returnValue = wrapper.RunTests("TestClass", new List <string> { "TestMethod1", "TestMethod2" }, node => { lastNode = node; return(true); }); Assert.Equal(returnValue, lastNode); Assert.Equal(2, lastNode.ChildNodes.Count); // Two test results XmlNode result0 = ResultXmlUtility.GetResult(lastNode, 0); Assert.Equal("Pass", result0.Attributes["result"].Value); XmlNode result1 = ResultXmlUtility.GetResult(lastNode, 1); Assert.Equal("Pass", result1.Attributes["result"].Value); } }
public void NonTestMethodInClassWithTestMethod() { string code = @" using Xunit; public class TestClass { public void NonTestMethod() { } [Fact] public void TestMethod() { } }"; using (MockAssembly assembly = new MockAssembly()) { assembly.Compile(code); XmlNode lastNode = null; using (ExecutorWrapper wrapper = new ExecutorWrapper(assembly.FileName, null, false)) wrapper.RunTest("TestClass", "NonTestMethod", node => { lastNode = node; return(true); }); Assert.Equal("class", lastNode.Name); Assert.Equal(0, lastNode.ChildNodes.Count); // Empty class node } }
public void TestMethodWithNonTestMethod() { string code = @" using Xunit; public class TestClass { [Fact] public void TestMethod1() {} [Fact] public void TestMethod2() {} [Fact] public void TestMethod3() {} public void NonTestMethod() {} }"; using (MockAssembly assembly = new MockAssembly()) { assembly.Compile(code); XmlNode lastNode = null; using (ExecutorWrapper wrapper = new ExecutorWrapper(assembly.FileName, null, false)) wrapper.RunTests("TestClass", new List <string> { "TestMethod1", "NonTestMethod" }, node => { lastNode = node; return(true); }); Assert.Single(lastNode.ChildNodes); // Only the test method XmlNode result = ResultXmlUtility.GetResult(lastNode, 0); Assert.Equal("Pass", result.Attributes["result"].Value); } }
public void CallbackIncludesStartMessages() { const string code = @" using Xunit; public class TestClass { [Fact] public void TestMethod1() {} [Fact] public void TestMethod2() {} [Fact] public void TestMethod3() {} }"; using (MockAssembly assembly = new MockAssembly()) { assembly.Compile(code); List <XmlNode> nodes = new List <XmlNode>(); using (ExecutorWrapper wrapper = new ExecutorWrapper(assembly.FileName, null, false)) wrapper.RunTests("TestClass", new List <string> { "TestMethod1" }, node => { nodes.Add(node); return(true); }); Assert.Equal(3, nodes.Count); Assert.Equal("start", nodes[0].Name); // <start> ResultXmlUtility.AssertAttribute(nodes[0], "name", "TestClass.TestMethod1"); ResultXmlUtility.AssertAttribute(nodes[0], "type", "TestClass"); ResultXmlUtility.AssertAttribute(nodes[0], "method", "TestMethod1"); Assert.Equal("test", nodes[1].Name); Assert.Equal("class", nodes[2].Name); } }
public void AmbiguousMethodName() { string code = @" using Xunit; public class TestClass { public void DummyMethod() {} public void DummyMethod(string s) {} public void DummyMethod2() {} }"; using (MockAssembly assembly = new MockAssembly()) { assembly.Compile(code); using (ExecutorWrapper wrapper = new ExecutorWrapper(assembly.FileName, null, false)) Assert.Throws <ArgumentException>( () => wrapper.RunTests("TestClass", new List <string> { "DummyMethod", "DummyMethod2" }, null)); } }
static IEnumerable <TestCase> GetTestCases(ExecutorWrapper executor) { foreach (XmlNode methodNode in executor.EnumerateTests().SelectNodes("//method")) { yield return(GetTestCase(executor.AssemblyFilename, methodNode)); } }
public void NonPublicTestMethod() { string code = @" using Xunit; public class TestClass { [Fact] void NonPublicTestMethod() {} }"; using (MockAssembly assembly = new MockAssembly()) { assembly.Compile(code); XmlNode returnValue = null; using (ExecutorWrapper wrapper = new ExecutorWrapper(assembly.FileName, null, false)) returnValue = wrapper.RunTests("TestClass", new List <string> { "NonPublicTestMethod" }, node => { return(true); }); Assert.Single(returnValue.ChildNodes); XmlNode result = ResultXmlUtility.GetResult(returnValue, 0); Assert.Equal("Pass", result.Attributes["result"].Value); } }
TestRunState ITdNetTestRunner.RunMember(ITestListener listener, Assembly assembly, MemberInfo member) { try { using (ExecutorWrapper wrapper = new ExecutorWrapper(new Uri(assembly.CodeBase).LocalPath, null, false)) { TdNetLogger logger = new TdNetLogger(listener, assembly); TestRunner runner = new TestRunner(wrapper, logger); MethodInfo method = member as MethodInfo; if (method != null) return RunMethod(runner, method); Type type = member as Type; if (type != null) return RunClassWithInnerTypes(runner, type); return TestRunState.NoTests; } } catch (ArgumentException) { return TestRunState.NoTests; } }
TestRunState ITdNetTestRunner.RunMember(ITestListener listener, Assembly assembly, MemberInfo member) { try { using (ExecutorWrapper wrapper = new ExecutorWrapper(new Uri(assembly.CodeBase).LocalPath, null, false)) { TdNetLogger logger = new TdNetLogger(listener, assembly); TestRunner runner = new TestRunner(wrapper, logger); MethodInfo method = member as MethodInfo; if (method != null) { return(RunMethod(runner, method)); } Type type = member as Type; if (type != null) { return(RunClassWithInnerTypes(runner, type)); } return(TestRunState.NoTests); } } catch (ArgumentException) { return(TestRunState.NoTests); } }
// Tell ReSharper the cache folder being used for shadow copy, so that if // someone kills this process (e.g. user aborts), ReSharper can delete it. // xunit doesn't expose this information, so we'll grab it via (sorry) reflection private void SetTempFolderPath(ExecutorWrapper executorWrapper) { if (!configuration.ShadowCopy) { return; } var fieldInfo = executorWrapper.GetType().GetField("appDomain", BindingFlags.NonPublic | BindingFlags.Instance); if (fieldInfo == null) { throw new InvalidOperationException("Expected ExecutorWrapped to contain private field \"appDomain\""); } var appDomain = fieldInfo.GetValue(executorWrapper) as AppDomain; if (appDomain != null) { var cachePath = appDomain.SetupInformation.CachePath; if (!string.IsNullOrEmpty(cachePath)) { server.SetTempFolderPath(cachePath); } } }
public SimpleProject() { var source = new BuildSource { TargetDir = TargetDir, References = { BuildReference.ByName("System.Collections.Immutable", copyLocal: true), BuildReference.ByName("System.Interactive.Async", copyLocal: true), BuildReference.ByName("System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"), BuildReference.ByName("EntityFramework.Core", copyLocal: true), BuildReference.ByName("EntityFramework.Commands", copyLocal: true), BuildReference.ByName("EntityFramework.Relational", copyLocal: true), BuildReference.ByName("EntityFramework.Relational.Design", copyLocal: true), BuildReference.ByName("EntityFramework.SqlServer", copyLocal: true), BuildReference.ByName("Microsoft.CodeAnalysis", copyLocal: true), BuildReference.ByName("Microsoft.Framework.Caching.Abstractions", copyLocal: true), BuildReference.ByName("Microsoft.Framework.Caching.Memory", copyLocal: true), BuildReference.ByName("Microsoft.Framework.DependencyInjection", copyLocal: true), BuildReference.ByName("Microsoft.Framework.DependencyInjection.Abstractions", copyLocal: true), BuildReference.ByName("Microsoft.Framework.Logging", copyLocal: true), BuildReference.ByName("Microsoft.Framework.Logging.Abstractions", copyLocal: true), BuildReference.ByName("Microsoft.Framework.OptionsModel", copyLocal: true), BuildReference.ByName("Remotion.Linq", copyLocal: true) }, Sources = { @" using Microsoft.Data.Entity; using Microsoft.Data.Entity.Infrastructure; using Microsoft.Data.Entity.Migrations; namespace SimpleProject { internal class SimpleContext : DbContext { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer(""Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=SimpleProject.SimpleContext;Integrated Security=True""); } } namespace Migrations { [DbContext(typeof(SimpleContext))] public class InitialCreate : Migration { public override string Id => ""201410102227260_InitialCreate""; protected override void Up(MigrationBuilder migrationBuilder) { } } } }" } }; var build = source.Build(); Executor = new ExecutorWrapper(TargetDir, build.TargetName + ".dll", TargetDir, "SimpleProject"); }
static string Run(string className, System.Reflection.Assembly koanAssembly, ExecutorWrapper wrapper) { Type classToRun = koanAssembly.GetType(className); if (classToRun == null) { return("(0/0)"); } string[] queue = new string[classToRun.GetMethods().Length + 1]; int highestKoanNumber = 0; foreach (MethodInfo method in classToRun.GetMethods()) { if (method.Name == null) { continue; } DotNetKoans.KoanAttribute custAttr = method.GetCustomAttributes(typeof(DotNetKoans.KoanAttribute), false).FirstOrDefault() as DotNetKoans.KoanAttribute; if (custAttr == null) { continue; } queue[custAttr.Position] = method.Name; if (custAttr.Position > highestKoanNumber) { highestKoanNumber = custAttr.Position; } } int numberOfTestsActuallyRun = 0; int numberOfTestsPassed = 0; foreach (string test in queue) { if (String.IsNullOrEmpty(test)) { continue; } numberOfTestsActuallyRun++; if (TEST_FAILED != 0) { continue; } wrapper.RunTest(className, test, callback); if (TEST_FAILED == 0) { numberOfTestsPassed++; } } if (numberOfTestsActuallyRun != highestKoanNumber) { Console.WriteLine("!!!!WARNING - Some Koans appear disabled. The highest koan found was {0} but we ran {1} koan(s)", highestKoanNumber, numberOfTestsActuallyRun); } return(string.Format("({0}/{1})", numberOfTestsPassed, numberOfTestsActuallyRun)); }
static int Main(string[] args) { try { Console.WriteLine(""); Console.WriteLine(""); Console.WriteLine("*******************************************************************"); Console.WriteLine("*******************************************************************"); ReadProgress(); string koan_path = args[0]; Xunit.ExecutorWrapper wrapper = new ExecutorWrapper(koan_path, null, false); System.Reflection.Assembly koans = System.Reflection.Assembly.LoadFrom(koan_path); if (koans == null) { Console.WriteLine("Bad Assembly"); return(-1); } Type pathType = null; foreach (Type type in koans.GetExportedTypes()) { if (typeof(KoanHelpers.IAmThePathToEnlightenment).IsAssignableFrom(type)) { pathType = type; break; } } KoanHelpers.IAmThePathToEnlightenment path = Activator.CreateInstance(pathType) as KoanHelpers.IAmThePathToEnlightenment; string thePath = path.ThePath; string[] theKoanNames = KoanNames; foreach (string koanName in theKoanNames) { Run(thePath + "." + koanName, koans, wrapper); } Console.WriteLine("{0}", Encouragement()); progress.Add(firstFailingKoan); WriteProgress(); } catch (Exception ex) { Console.WriteLine("Karma has killed the runner. Exception was: " + ex.ToString()); return(-1); } if (!aKoanHasFailed) { firstFailingKoan = numberKoansProcessed; } Console.WriteLine("Koan progress: {0}/{1}", firstFailingKoan, numberKoansProcessed); Console.WriteLine("*******************************************************************"); Console.WriteLine("*******************************************************************"); Console.WriteLine(""); Console.WriteLine(""); return(0); }
/// <summary> /// Run all the unit tests in the class /// </summary> /// <param name="assemblyPath">The assembly that contains the unit test.</param> /// <param name="className">The full name of the class that contains the unit test.</param> override public void RunTests(string assemblyPath, string assemblyName) { System.Xml.XmlNode returnValue = null; using (ExecutorWrapper wrapper = new ExecutorWrapper(assemblyPath, null, true)) { returnValue = wrapper.RunAssembly(node => true); } ParseResults(returnValue); }
public void AssemblyWithNoTests() { string code = @" public class JustAPlainOldClass { }"; using (MockAssembly assembly = new MockAssembly()) { assembly.Compile(code); using (ExecutorWrapper wrapper = new ExecutorWrapper(assembly.FileName, null, false)) Assert.Equal(0, wrapper.GetAssemblyTestCount()); } }
static int Main(string[] args) { StringBuilder progress = new StringBuilder(); try { Console.WriteLine(""); Console.WriteLine(""); Console.WriteLine("*******************************************************************"); Console.WriteLine("*******************************************************************"); string koan_path = args[0]; Xunit.ExecutorWrapper wrapper = new ExecutorWrapper(koan_path, null, false); System.Reflection.Assembly koans = System.Reflection.Assembly.LoadFrom(koan_path); if (koans == null) { Console.WriteLine("Bad Assembly"); return(-1); } Type pathType = null; foreach (Type type in koans.GetExportedTypes()) { if (typeof(KoanHelpers.IAmThePathToEnlightenment).IsAssignableFrom(type)) { pathType = type; break; } } KoanHelpers.IAmThePathToEnlightenment path = Activator.CreateInstance(pathType) as KoanHelpers.IAmThePathToEnlightenment; string[] thePath = path.ThePath; foreach (string koan in thePath) { progress.AppendFormat("{0},", Run(koan, koans, wrapper)); } } catch (Exception ex) { Console.WriteLine("Karma has killed the runner. Exception was: " + ex.ToString()); return(-1); } Console.WriteLine("Koan progress:{0}", progress.ToString()); Console.WriteLine("*******************************************************************"); Console.WriteLine("*******************************************************************"); Console.WriteLine(""); Console.WriteLine(""); return(TEST_FAILED); }
public void DiscoverTests(IEnumerable<string> sources, IMessageLogger logger, ITestCaseDiscoverySink discoverySink) { Guard.ArgumentNotNull("sources", sources); Guard.ArgumentNotNull("logger", logger); Guard.ArgumentNotNull("discoverySink", discoverySink); foreach (string source in sources) try { if (IsXunitTestAssembly(source)) using (ExecutorWrapper executor = new ExecutorWrapper(source, configFilename: null, shadowCopy: true)) foreach (TestCase testCase in GetTestCases(executor)) discoverySink.SendTestCase(testCase); } catch (Exception e) { logger.SendMessage(TestMessageLevel.Error, String.Format("xUnit.net: Exception discovering tests from {0}: {1}", source, e)); } }
public void InvalidMethodName() { string code = @" using Xunit; public class TestClass { }"; using (MockAssembly assembly = new MockAssembly()) { assembly.Compile(code); using (ExecutorWrapper wrapper = new ExecutorWrapper(assembly.FileName, null, false)) Assert.Throws <ArgumentException>(() => wrapper.RunTest("TestClass", "DummyMethod", null)); } }
// ITestRunner implementation TestRunState ITdNetTestRunner.RunAssembly(ITestListener listener, Assembly assembly) { string assemblyFilename = new Uri(assembly.CodeBase).LocalPath; try { using (ExecutorWrapper wrapper = new ExecutorWrapper(assemblyFilename, null, false)) { TdNetLogger logger = new TdNetLogger(listener, assembly); TestRunner runner = new TestRunner(wrapper, logger); return RunAssembly(runner); } } catch (ArgumentException) { return TestRunState.NoTests; } }
// ITestRunner implementation TestRunState ITdNetTestRunner.RunAssembly(ITestListener listener, Assembly assembly) { string assemblyFilename = new Uri(assembly.CodeBase).LocalPath; try { using (ExecutorWrapper wrapper = new ExecutorWrapper(assemblyFilename, null, false)) { TdNetLogger logger = new TdNetLogger(listener, assembly); TestRunner runner = new TestRunner(wrapper, logger); return(RunAssembly(runner)); } } catch (ArgumentException) { return(TestRunState.NoTests); } }
public XmlNode Run(string configFile) { using (ExecutorWrapper wrapper = new ExecutorWrapper(FileName, configFile, false)) { XmlNode result = null; wrapper.RunAssembly(node => { if (node.Name == "assembly") { result = node; } return(true); }); return(result); } }
void RunTestsInAssembly(string assemblyFileName, IRunContext ctxt, ITestExecutionRecorder recorder, IEnumerable <TestCase> testCases = null) { cancelled = false; using (var executor = new ExecutorWrapper(assemblyFileName, configFilename: null, shadowCopy: true)) { if (testCases == null) { testCases = VsTestRunner.GetTestCases(executor).ToArray(); } var logger = new VsRunnerLogger(recorder, testCases, () => cancelled); var runner = new TestRunner(executor, logger); foreach (var testClass in testCases.Select(tc => new TypeAndMethod(tc.Name)) .GroupBy(tam => tam.Type)) { runner.RunTests(testClass.Key, testClass.Select(tam => tam.Method).ToList()); } } }
public void SuccessfulConstructionCanReturnConfigFilename() { string code = @" using Xunit; public class TestClass { [Fact] public void TestMethod() { } }"; using (MockAssembly assembly = new MockAssembly()) { assembly.Compile(code); using (ExecutorWrapper wrapper = new ExecutorWrapper(assembly.FileName, @"C:\Foo\bar.config", false)) Assert.Equal(@"C:\Foo\bar.config", wrapper.ConfigFilename); } }
public void ClassWhichHasNoTests() { string code = @" using Xunit; public class PlainOldDotNetClass { }"; using (MockAssembly assembly = new MockAssembly()) { assembly.Compile(code); XmlNode lastNode = null; using (ExecutorWrapper wrapper = new ExecutorWrapper(assembly.FileName, null, false)) wrapper.RunClass("PlainOldDotNetClass", node => { lastNode = node; return(true); }); Assert.Equal("class", lastNode.Name); Assert.Equal(0, lastNode.ChildNodes.Count); // Empty class node } }
public void AssemblyWithNoTests() { string code = @" using Xunit; public class PlainOldDotNetClass { }"; using (MockAssembly assembly = new MockAssembly()) { assembly.Compile(code); XmlNode lastNode = null; using (ExecutorWrapper wrapper = new ExecutorWrapper(assembly.FileName, null, false)) wrapper.RunAssembly(node => { lastNode = node; return(true); }); Assert.NotNull(lastNode); // Always get an <assembly> node, even if there are no tests Assert.Equal(0, lastNode.ChildNodes.Count); } }
string ExecuteAssembly(string assemblyFilename, string configFilename, IRunnerLogger logger) { try { using (ExecutorWrapper wrapper = new ExecutorWrapper(assemblyFilename, configFilename, ShadowCopy)) { Log.LogMessage(MessageImportance.High, "xunit.dll: Version {0}", wrapper.XunitVersion); Log.LogMessage(MessageImportance.High, "Test assembly: {0}", assemblyFilename); XmlTestRunner runner = new XmlTestRunner(wrapper, logger); if (runner.RunAssembly() == TestRunnerResult.Failed) { ExitCode = -1; } return(runner.Xml); } } catch (Exception ex) { Exception e = ex; while (e != null) { Log.LogError(e.GetType().FullName + ": " + e.Message); foreach (string stackLine in e.StackTrace.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)) { Log.LogError(stackLine); } e = e.InnerException; } ExitCode = -1; return(""); } }
public void SuccessfulConstructionCanReturnXunitDllVersion() { string code = @" using Xunit; public class TestClass { [Fact] public void TestMethod() { } }"; AssemblyName xunitName = XunitAssemblyName; using (MockAssembly assembly = new MockAssembly()) { assembly.Compile(code); using (ExecutorWrapper wrapper = new ExecutorWrapper(assembly.FileName, null, false)) Assert.Equal(xunitName.Version.ToString(), wrapper.XunitVersion); } }
public void DiscoverTests(IEnumerable <string> sources, IMessageLogger logger, ITestCaseDiscoverySink discoverySink) { Guard.ArgumentNotNull("sources", sources); Guard.ArgumentNotNull("logger", logger); Guard.ArgumentNotNull("discoverySink", discoverySink); foreach (string source in sources) { try { if (IsXunitTestAssembly(source)) { using (ExecutorWrapper executor = new ExecutorWrapper(source, configFilename: null, shadowCopy: true)) foreach (TestCase testCase in GetTestCases(executor)) { discoverySink.SendTestCase(testCase); } } } catch (Exception e) { logger.SendMessage(TestMessageLevel.Error, String.Format("xUnit.net: Exception discovering tests from {0}: {1}", source, e)); } } }
public ProjectExecutionContext(Project project, IServiceProvider serviceProvider) { Debug.Assert(project != null, "project is null."); Debug.Assert(!VsUtils.IsMiscellaneousProject(project), "project is misc files project."); _domain = AppDomain.CreateDomain( "ProjectExecutionContextDomain", null, new AppDomainSetup { ApplicationBase = VsUtils.GetProjectTargetDir(project, serviceProvider), ConfigurationFile = VsUtils.GetProjectConfigurationFile(project, serviceProvider), ShadowCopyFiles = "true" // Prevents locking }); var dataDirectory = VsUtils.GetProjectDataDirectory(project, serviceProvider); if (dataDirectory != null) { _domain.SetData("DataDirectory", dataDirectory); } _executor = new ExecutorWrapper(_domain, VsUtils.GetProjectTargetFileName(project)); }
static int RunProject(XunitProject project, bool teamcity, bool silent) { int totalAssemblies = 0; int totalTests = 0; int totalFailures = 0; int totalSkips = 0; double totalTime = 0; foreach (XunitProjectAssembly assembly in project.Assemblies) using (ExecutorWrapper wrapper = new ExecutorWrapper(assembly.AssemblyFilename, assembly.ConfigFilename, assembly.ShadowCopy)) { Console.WriteLine(); Console.WriteLine("xunit.dll: Version {0}", wrapper.XunitVersion); Console.WriteLine("Test assembly: {0}", Path.GetFullPath(assembly.AssemblyFilename)); Console.WriteLine(); try { List<IResultXmlTransform> transforms = TransformFactory.GetAssemblyTransforms(assembly); Logger logger = teamcity ? (Logger)new TeamCityLogger() : new StandardLogger(silent, wrapper.GetAssemblyTestCount()); new TestRunner(wrapper, logger).RunAssembly(transforms); ++totalAssemblies; totalTests += logger.TotalTests; totalFailures += logger.TotalFailures; totalSkips += logger.TotalSkips; totalTime += logger.TotalTime; } catch (ArgumentException ex) { Console.WriteLine(ex.Message); } } if (!teamcity && totalAssemblies > 1) { Console.WriteLine(); Console.WriteLine("=== {0} total, {1} failed, {2} skipped, took {3} seconds ===", totalTests, totalFailures, totalSkips, totalTime.ToString("0.000", CultureInfo.InvariantCulture)); } return totalFailures; }
TestRunState ITdNetTestRunner.RunNamespace(ITestListener listener, Assembly assembly, string ns) { try { using (ExecutorWrapper wrapper = new ExecutorWrapper(new Uri(assembly.CodeBase).LocalPath, null, false)) { TdNetLogger logger = new TdNetLogger(listener, assembly); TestRunner runner = new TestRunner(wrapper, logger); TestRunState runState = TestRunState.NoTests; foreach (Type type in assembly.GetExportedTypes()) if (ns == null || type.Namespace == ns) runState = TestResultMapper.Merge(runState, RunClass(runner, type)); return runState; } } catch (ArgumentException) { return TestRunState.NoTests; } }
public override bool Execute() { try { string assemblyFilename = Assembly.GetMetadata("FullPath"); if (WorkingFolder != null) Directory.SetCurrentDirectory(WorkingFolder); using (ExecutorWrapper wrapper = new ExecutorWrapper(assemblyFilename, ConfigFile, ShadowCopy)) { Log.LogMessage(MessageImportance.High, "xUnit.net MSBuild runner ({0}-bit .NET {1})", IntPtr.Size * 8, Environment.Version); Log.LogMessage(MessageImportance.High, "Test assembly: {0}", assemblyFilename); Log.LogMessage(MessageImportance.High, "xunit.dll version: {0}", wrapper.XunitVersion); IRunnerLogger logger = TeamCity ? (IRunnerLogger)new TeamCityLogger(Log) : Verbose ? new VerboseLogger(Log) : new StandardLogger(Log); List<IResultXmlTransform> transforms = new List<IResultXmlTransform>(); using (Stream htmlStream = ResourceStream("HTML.xslt")) using (Stream nunitStream = ResourceStream("NUnitXml.xslt")) { if (Xml != null) transforms.Add(new NullTransformer(Xml.GetMetadata("FullPath"))); if (Html != null) transforms.Add(new XslStreamTransformer(htmlStream, Html.GetMetadata("FullPath"))); if (NUnitXml != null) transforms.Add(new XslStreamTransformer(nunitStream, NUnitXml.GetMetadata("FullPath"))); TestRunner runner = new TestRunner(wrapper, logger); if (runner.RunAssembly(transforms) == TestRunnerResult.Failed) { ExitCode = -1; return false; } ExitCode = 0; return true; } } } catch (Exception ex) { Exception e = ex; while (e != null) { Log.LogError(e.GetType().FullName + ": " + e.Message); foreach (string stackLine in e.StackTrace.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)) Log.LogError(stackLine); e = e.InnerException; } ExitCode = -1; return false; } }
public override bool Execute() { RemotingUtility.CleanUpRegisteredChannels(); try { ExitCode = 0; string projectFilename = ProjectFile.GetMetadata("FullPath"); XunitProject project = XunitProject.Load(projectFilename); IRunnerLogger logger = TeamCity ? (IRunnerLogger)new TeamCityLogger(Log, () => cancel) : Verbose ? new VerboseLogger(Log, () => cancel) : new StandardLogger(Log, () => cancel); Log.LogMessage(MessageImportance.High, "xUnit.net MSBuild runner ({0}-bit .NET {1})", IntPtr.Size * 8, Environment.Version); foreach (XunitProjectAssembly assembly in project.Assemblies) { if (cancel) break; using (Stream htmlStream = ResourceStream("HTML.xslt")) using (Stream nunitStream = ResourceStream("NUnitXml.xslt")) using (ExecutorWrapper wrapper = new ExecutorWrapper(assembly.AssemblyFilename, assembly.ConfigFilename, assembly.ShadowCopy)) { Log.LogMessage(MessageImportance.High, " Test assembly: {0}", assembly.AssemblyFilename); Log.LogMessage(MessageImportance.High, " xunit.dll version: {0}", wrapper.XunitVersion); List<IResultXmlTransform> transforms = new List<IResultXmlTransform>(); foreach (KeyValuePair<string, string> kvp in assembly.Output) { switch (kvp.Key.ToLowerInvariant()) { case "xml": transforms.Add(new NullTransformer(kvp.Value)); break; case "html": transforms.Add(new XslStreamTransformer(htmlStream, kvp.Value)); break; case "nunit": transforms.Add(new XslStreamTransformer(nunitStream, kvp.Value)); break; default: Log.LogWarning("Unknown output type: '{0}'", kvp.Key); break; } } TestRunner runner = new TestRunner(wrapper, logger); if (runner.RunAssembly(transforms) == TestRunnerResult.Failed) ExitCode = -1; } } StandardLogger stdLogger = logger as StandardLogger; if (stdLogger != null) { Log.LogMessage(MessageImportance.High, "TOTAL Tests: {0}, Failures: {1}, Skipped: {2}, Time: {3} seconds", stdLogger.Total, stdLogger.Failed, stdLogger.Skipped, stdLogger.Time.ToString("0.000")); } } catch (Exception ex) { Exception e = ex; while (e != null) { Log.LogError(e.GetType().FullName + ": " + e.Message); foreach (string stackLine in e.StackTrace.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)) Log.LogError(stackLine); e = e.InnerException; } ExitCode = -1; } return ExitCode == 0; }
void RunTestsInAssembly(List<ExecutorWrapper> cleanupList, string assemblyFileName, ITestExecutionRecorder recorder, IEnumerable<TestCase> testCases = null) { if (cancelled) return; var executor = new ExecutorWrapper(assemblyFileName, configFileName: null, shadowCopy: true); cleanupList.Add(executor); if (testCases == null) testCases = VsTestRunner.GetTestCases(executor).ToArray(); var logger = new VsRunnerLogger(recorder, testCases, () => cancelled); var runner = new TestRunner(executor, logger); foreach (var testClass in testCases.Select(tc => new TypeAndMethod(tc.FullyQualifiedName)) .GroupBy(tam => tam.Type)) { runner.RunTests(testClass.Key, testClass.Select(tam => tam.Method).ToList()); if (cancelled) return; } }
static IEnumerable<TestCase> GetTestCases(ExecutorWrapper executor) { string source = executor.AssemblyFilename; using (DiaSessionWrapper diaSession = new DiaSessionWrapper(source)) foreach (XmlNode methodNode in executor.EnumerateTests().SelectNodes("//method")) yield return GetTestCase(diaSession, source, methodNode); }
static IEnumerable<TestCase> GetTestCases(ExecutorWrapper executor) { foreach (XmlNode methodNode in executor.EnumerateTests().SelectNodes("//method")) yield return GetTestCase(executor.AssemblyFilename, methodNode); }
void RunTestsInAssembly(string assemblyFileName, IRunContext ctxt, ITestExecutionRecorder recorder, IEnumerable<TestCase> testCases = null) { cancelled = false; using (var executor = new ExecutorWrapper(assemblyFileName, configFilename: null, shadowCopy: true)) { if (testCases == null) testCases = VsTestRunner.GetTestCases(executor).ToArray(); var logger = new VsRunnerLogger(recorder, testCases, () => cancelled); var runner = new TestRunner(executor, logger); foreach (var testClass in testCases.Select(tc => new TypeAndMethod(tc.Name)) .GroupBy(tam => tam.Type)) runner.RunTests(testClass.Key, testClass.Select(tam => tam.Method).ToList()); } }
string ExecuteAssembly(string assemblyFilename, string configFilename, IRunnerLogger logger) { try { using (ExecutorWrapper wrapper = new ExecutorWrapper(assemblyFilename, configFilename, ShadowCopy)) { Log.LogMessage(MessageImportance.High, "xunit.dll: Version {0}", wrapper.XunitVersion); Log.LogMessage(MessageImportance.High, "Test assembly: {0}", assemblyFilename); XmlTestRunner runner = new XmlTestRunner(wrapper, logger); if (runner.RunAssembly() == TestRunnerResult.Failed) ExitCode = -1; return runner.Xml; } } catch (Exception ex) { Exception e = ex; while (e != null) { Log.LogError(e.GetType().FullName + ": " + e.Message); foreach (string stackLine in e.StackTrace.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)) Log.LogError(stackLine); e = e.InnerException; } ExitCode = -1; return ""; } }
/// <summary> /// Loads elements from specified location into memory /// /// This method uses exceptions for error conditions -- Not return values. /// </summary> /// <param name="assemblyFileLocation">Location to load tests from.</param> /// <param name="projectData">Project information object.</param> /// <param name="warningHandler">Warning handler that processes warnings.</param> /// <returns>The data that has been loaded</returns> public override ICollection Load(string assemblyFileLocation, ProjectData projectData, IWarningHandler warningHandler) { Guard.StringNotNullOrEmpty(assemblyFileLocation, "location"); IExecutorWrapper executor = null; try { // The ExecutorWrapper is the xUnit's version-resilient layer for communicating with different // versions of the main xunit.dll. The XUnitVSRunner is thus ignorant about that module and will // try to communicate and use whatever version is actually referenced in the unit test's assembly. executor = new ExecutorWrapper(assemblyFileLocation, configFilename: null, shadowCopy: true); } catch (ArgumentException ex) { Trace.WriteLine("No xUnit tests found in '" + assemblyFileLocation + "':"); Trace.WriteLine(ex); } #if DEBUG catch (Exception ex) { Trace.TraceError("Error at XUnitTestTip.Load: " + ex.Message); throw; } #endif var tests = new List<ITestElement>(); // Collection of tests loaded from disk if (executor == null) return tests; using (executor) { var testAssembly = TestAssemblyBuilder.Build(executor); // the magic is in this two-liner: we ask the xUnit to find all tests and then // with heavy use of Reflection we create the actual internal Microsoft's UnitTestElements // that will contain all required information about the test's location foreach (var xmethod in testAssembly.EnumerateTestMethods()) tests.Add(MSVST4U_Access.New_MSVST4U_UnitTestElement( assemblyFileLocation, xmethod.TestClass.TypeName, xmethod.MethodName, projectData)); } return tests; }