in src/Adapter/MSTest.CoreAdapter/Discovery/UnitTestDiscoverer.cs [88:168]
internal void SendTestCases(string source, IEnumerable<UnitTestElement> testElements, ITestCaseDiscoverySink discoverySink, IDiscoveryContext discoveryContext, IMessageLogger logger)
{
var shouldCollectSourceInformation = MSTestSettings.RunConfigurationSettings.CollectSourceInformation;
var navigationSessions = new Dictionary<string, object>();
try
{
if (shouldCollectSourceInformation)
{
navigationSessions.Add(source, PlatformServiceProvider.Instance.FileOperations.CreateNavigationSession(source));
}
// Get filter expression and skip discovery in case filter expression has parsing error.
ITestCaseFilterExpression filterExpression = this.TestMethodFilter.GetFilterExpression(discoveryContext, logger, out var filterHasError);
if (filterHasError)
{
return;
}
foreach (var testElement in testElements)
{
var testCase = testElement.ToTestCase();
// Filter tests based on test case filters
if (filterExpression != null && filterExpression.MatchTestCase(testCase, (p) => this.TestMethodFilter.PropertyValueProvider(testCase, p)) == false)
{
continue;
}
if (shouldCollectSourceInformation)
{
string testSource = testElement.TestMethod.DeclaringAssemblyName ?? source;
if (!navigationSessions.TryGetValue(testSource, out var testNavigationSession))
{
testNavigationSession = PlatformServiceProvider.Instance.FileOperations.CreateNavigationSession(testSource);
navigationSessions.Add(testSource, testNavigationSession);
}
if (testNavigationSession != null)
{
var className = testElement.TestMethod.DeclaringClassFullName
?? testElement.TestMethod.FullClassName;
var methodName = testElement.TestMethod.Name;
// If it is async test method use compiler generated type and method name for navigation data.
if (!string.IsNullOrEmpty(testElement.AsyncTypeName))
{
className = testElement.AsyncTypeName;
// compiler generated method name is "MoveNext".
methodName = "MoveNext";
}
PlatformServiceProvider.Instance.FileOperations.GetNavigationData(
testNavigationSession,
className,
methodName,
out var minLineNumber,
out var fileName);
if (!string.IsNullOrEmpty(fileName))
{
testCase.LineNumber = minLineNumber;
testCase.CodeFilePath = fileName;
}
}
}
discoverySink.SendTestCase(testCase);
}
}
finally
{
foreach (object navigationSession in navigationSessions.Values)
{
PlatformServiceProvider.Instance.FileOperations.DisposeNavigationSession(navigationSession);
}
}
}