diff --git a/xunit.runner.visualstudio.nuspec b/xunit.runner.visualstudio.nuspec
index 8a075f52..10ab5bcc 100644
--- a/xunit.runner.visualstudio.nuspec
+++ b/xunit.runner.visualstudio.nuspec
@@ -24,6 +24,9 @@ Supported platforms:
+
+
+
diff --git a/xunit.runner.visualstudio.testadapter/Sinks/VsDiscoverySink.cs b/xunit.runner.visualstudio.testadapter/Sinks/VsDiscoverySink.cs
index 15abbd34..fb647fe9 100644
--- a/xunit.runner.visualstudio.testadapter/Sinks/VsDiscoverySink.cs
+++ b/xunit.runner.visualstudio.testadapter/Sinks/VsDiscoverySink.cs
@@ -6,6 +6,8 @@
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;
using Xunit.Abstractions;
+using Xunit.Sdk;
+using Newtonsoft.Json;
#if PLATFORM_DOTNET
using System.Reflection;
@@ -65,14 +67,32 @@ public static TestCase CreateVsTestCase(string source, ITestFrameworkDiscoverer
{
try
{
- var serializedTestCase = discoverer.Serialize(xunitTestCase);
var fqTestMethodName = $"{xunitTestCase.TestMethod.TestClass.Class.Name}.{xunitTestCase.TestMethod.Method.Name}";
var uniqueName = forceUniqueNames ? $"{fqTestMethodName} ({xunitTestCase.UniqueID})" : fqTestMethodName;
var result = new TestCase(uniqueName, uri, source) { DisplayName = Escape(xunitTestCase.DisplayName) };
- result.SetPropertyValue(VsTestRunner.SerializedTestCaseProperty, serializedTestCase);
+
+ if (VsTestRunner.AppDomain != AppDomainSupport.Denied)
+ {
+ var serializedTestCase = discoverer.Serialize(xunitTestCase);
+ result.SetPropertyValue(VsTestRunner.SerializedTestCaseProperty, serializedTestCase);
+ }
result.Id = GuidFromString(uri + xunitTestCase.UniqueID);
+ if (xunitTestCase.TestMethodArguments != null)
+ {
+ var serializedTestArguments = JsonConvert.SerializeObject(xunitTestCase.TestMethodArguments, new JsonSerializerSettings
+ {
+ TypeNameHandling = TypeNameHandling.Auto
+ });
+ result.SetPropertyValue(VsTestRunner.SerializedTestCaseArgumentProperty, serializedTestArguments);
+ }
+
+ if (xunitTestCase is XunitTheoryTestCase)
+ {
+ result.SetPropertyValue(VsTestRunner.TheoryAgrumentProperty, "Theory");
+ }
+
if (addTraitThunk != null)
{
foreach (var key in xunitTestCase.Traits.Keys)
diff --git a/xunit.runner.visualstudio.testadapter/Utility/AssemblyRunInfo.cs b/xunit.runner.visualstudio.testadapter/Utility/AssemblyRunInfo.cs
index 13c4a02c..95b25698 100644
--- a/xunit.runner.visualstudio.testadapter/Utility/AssemblyRunInfo.cs
+++ b/xunit.runner.visualstudio.testadapter/Utility/AssemblyRunInfo.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
+using Xunit.Abstractions;
namespace Xunit.Runner.VisualStudio
{
@@ -8,5 +9,6 @@ public class AssemblyRunInfo
public string AssemblyFileName;
public TestAssemblyConfiguration Configuration;
public IList TestCases;
+ public Dictionary TestCaseMap;
}
}
diff --git a/xunit.runner.visualstudio.testadapter/VsTestRunner.cs b/xunit.runner.visualstudio.testadapter/VsTestRunner.cs
index edbd7f1f..c4a44253 100644
--- a/xunit.runner.visualstudio.testadapter/VsTestRunner.cs
+++ b/xunit.runner.visualstudio.testadapter/VsTestRunner.cs
@@ -9,6 +9,9 @@
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
using Xunit.Abstractions;
+using System.Reflection;
+using Xunit.Sdk;
+using Newtonsoft.Json;
#if !PLATFORM_DOTNET
using System.Xml;
@@ -24,11 +27,13 @@ namespace Xunit.Runner.VisualStudio.TestAdapter
public class VsTestRunner : ITestDiscoverer, ITestExecutor
{
public static TestProperty SerializedTestCaseProperty = GetTestProperty();
+ public static TestProperty SerializedTestCaseArgumentProperty = GetTestArgumentProperty();
+ public static TestProperty TheoryAgrumentProperty = GetTheoryAgrumentProperty();
#if PLATFORM_DOTNET
- static readonly AppDomainSupport AppDomainDefaultBehavior = AppDomainSupport.Denied;
+ internal static AppDomainSupport AppDomain = AppDomainSupport.Denied;
#else
- static readonly AppDomainSupport AppDomainDefaultBehavior = AppDomainSupport.Required;
+ internal static AppDomainSupport AppDomain = AppDomainSupport.Required;
#endif
static readonly HashSet platformAssemblies = new HashSet(StringComparer.OrdinalIgnoreCase)
@@ -111,10 +116,16 @@ void ITestExecutor.RunTests(IEnumerable tests, IRunContext runContext,
var stopwatch = Stopwatch.StartNew();
var logger = new LoggerHelper(frameworkHandle, stopwatch);
+ Dictionary testCaseMap = null;
+ if (AppDomain == AppDomainSupport.Denied)
+ {
+ testCaseMap = GetXunitTestCaseMap(tests);
+ }
+
RunTests(
runContext, frameworkHandle, logger,
() => tests.GroupBy(testCase => testCase.Source)
- .Select(group => new AssemblyRunInfo { AssemblyFileName = group.Key, Configuration = LoadConfiguration(group.Key), TestCases = group.ToList() })
+ .Select(group => new AssemblyRunInfo { AssemblyFileName = group.Key, Configuration = LoadConfiguration(group.Key), TestCases = group.ToList(), TestCaseMap = testCaseMap })
.ToList()
);
}
@@ -257,6 +268,12 @@ static Stream GetConfigurationStreamForAssembly(string assemblyName)
static TestProperty GetTestProperty()
=> TestProperty.Register("XunitTestCase", "xUnit.net Test Case", typeof(string), typeof(VsTestRunner));
+ static TestProperty GetTestArgumentProperty()
+ => TestProperty.Register("XunitTestCaseArgument", "xUnit.net Test Case Argument", typeof(string), typeof(object[]));
+
+ static TestProperty GetTheoryAgrumentProperty()
+ => TestProperty.Register("TheoryAgrument", "xUnit.net Theory Argument", typeof(string), typeof(object[]));
+
List GetTests(IEnumerable sources, LoggerHelper logger, IRunContext runContext)
{
// For store apps, the files are copied to the AppX dir, we need to load it from there
@@ -280,16 +297,45 @@ List GetTests(IEnumerable sources, LoggerHelper logger,
vsFilteredTestCases = filterHelper.GetFilteredTestList(vsFilteredTestCases, runContext, logger, source).ToList();
// Re-create testcases with unique names if there is more than 1
- var testCases = visitor.TestCases.Where(tc => vsFilteredTestCases.Any(vsTc => vsTc.DisplayName == tc.DisplayName))
- .GroupBy(tc => $"{tc.TestMethod.TestClass.Class.Name}.{tc.TestMethod.Method.Name}")
- .SelectMany(group => group.Select(testCase => VsDiscoverySink.CreateVsTestCase(source, discoverer, testCase, forceUniqueNames: group.Count() > 1, logger: logger, knownTraitNames: knownTraitNames))
- .Where(vsTestCase => vsTestCase != null)).ToList(); // pre-enumerate these as it populates the known trait names collection
+ Dictionary testCaseMap = null;
+ List testCases = null;
+
+ if (AppDomain == AppDomainSupport.Denied)
+ {
+ testCaseMap = visitor.TestCases.Where(tc => vsFilteredTestCases.Any(vsTc => vsTc.DisplayName == tc.DisplayName)).GroupBy(tc => $"{tc.TestMethod.TestClass.Class.Name}.{tc.TestMethod.Method.Name}")
+ .SelectMany(group => group.Select((testCase, i) => new
+ {
+ testCase,
+ v = VsDiscoverySink.CreateVsTestCase(
+ source,
+ discoverer,
+ testCase,
+ forceUniqueNames: group.Count() > 1,
+ logger: logger,
+ knownTraitNames: knownTraitNames)
+ })).ToDictionary(x => x.testCase, x => x.v);
+
+ }
+ else
+ {
+ testCases = visitor.TestCases.Where(tc => vsFilteredTestCases.Any(vsTc => vsTc.DisplayName == tc.DisplayName)).GroupBy(tc => $"{tc.TestMethod.TestClass.Class.Name}.{tc.TestMethod.Method.Name}")
+ .SelectMany(group => group.Select(testCase =>
+ VsDiscoverySink.CreateVsTestCase(
+ source,
+ discoverer,
+ testCase,
+ forceUniqueNames: group.Count() > 1,
+ logger: logger,
+ knownTraitNames: knownTraitNames))
+ .Where(vsTestCase => vsTestCase != null)).ToList(); // pre-enumerate these as it populates the known trait names collection
+ }
var runInfo = new AssemblyRunInfo
{
AssemblyFileName = source,
Configuration = LoadConfiguration(source),
- TestCases = testCases
+ TestCases = testCases,
+ TestCaseMap = testCaseMap
};
result.Add(runInfo);
}
@@ -377,9 +423,18 @@ void RunTestsInAssembly(IRunContext runContext,
var diagnosticMessageVisitor = new DiagnosticMessageSink(logger, assemblyDisplayName, runInfo.Configuration.DiagnosticMessagesOrDefault);
using (var controller = new XunitFrontController(appDomain, assemblyFileName: assemblyFileName, configFileName: null, shadowCopy: shadowCopy, diagnosticMessageSink: diagnosticMessageVisitor))
{
- var xunitTestCases = runInfo.TestCases.Select(tc => new { vs = tc, xunit = Deserialize(logger, controller, tc) })
- .Where(tc => tc.xunit != null)
- .ToDictionary(tc => tc.xunit, tc => tc.vs);
+ Dictionary xunitTestCases;
+ if (AppDomain == AppDomainSupport.Denied)
+ {
+ xunitTestCases = runInfo.TestCaseMap;
+ }
+ else
+ {
+ xunitTestCases = runInfo.TestCases.Select(tc => new { vs = tc, xunit = Deserialize(logger, controller, tc) })
+ .Where(tc => tc.xunit != null)
+ .ToDictionary(tc => tc.xunit, tc => tc.vs);
+ }
+
var executionOptions = TestFrameworkOptions.ForExecution(runInfo.Configuration);
executionOptions.SetSynchronousMessageReporting(true);
@@ -452,6 +507,111 @@ IEnumerator IEnumerable.GetEnumerator()
}
}
+ Dictionary GetXunitTestCaseMap(IEnumerable tests)
+ {
+ // -- Get the xunit ITestCase from TestCase
+ Dictionary testcaselist = new Dictionary();
+
+ var dict = new Dictionary();
+ foreach (TestCase test in tests)
+ {
+ var asmName = test.Source.Substring(test.Source.LastIndexOf('\\') + 1, test.Source.LastIndexOf('.') - test.Source.LastIndexOf('\\') - 1);
+ Assembly asm = null;
+ if (!dict.ContainsKey(asmName))
+ {
+#if PLATFORM_DOTNET
+ // todo : revisit this
+ asm = Assembly.Load(new AssemblyName(asmName));
+#else
+ asm = Assembly.LoadFrom(test.Source);
+#endif
+ dict.Add(asmName, asm);
+ }
+ else
+ {
+ asm = dict[asmName];
+ }
+
+ IAssemblyInfo assemblyInfo = new ReflectionAssemblyInfo(asm);
+ ITestAssembly testAssembly = new TestAssembly(assemblyInfo);
+
+ var lastIndexOfDot = test.FullyQualifiedName.LastIndexOf('.');
+ var testname = test.FullyQualifiedName.Split(' ')[0].Substring(lastIndexOfDot + 1);
+ var classname = test.FullyQualifiedName.Substring(0, lastIndexOfDot);
+
+ var methodClass = asm.GetType(classname);
+
+ ITypeInfo typeInfo = new ReflectionTypeInfo(methodClass);
+ TestCollection testCollection = new TestCollection(testAssembly, typeInfo, "Test collection for " + classname);
+ TestClass tc = new TestClass(testCollection, typeInfo);
+
+ //IMethodInfo
+#if PLATFORM_DOTNET
+ var methodinfos = methodClass.GetRuntimeMethods().ToList();
+#else
+ var methodinfos = methodClass.GetMethods().ToList();
+#endif
+
+ XunitTestCase xunitTestCase = null;
+ var serializedTestArgs = test.GetPropertyValue(SerializedTestCaseArgumentProperty, null);
+
+
+ Object[] testarguments = serializedTestArgs == null ? null : JsonConvert.DeserializeObject