Skip to content

Commit

Permalink
Merge branch 'main' into expand-tests + fix tests
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs
  • Loading branch information
Evangelink committed Dec 11, 2024
2 parents a4400e9 + 88286f6 commit 234c68f
Show file tree
Hide file tree
Showing 15 changed files with 102 additions and 87 deletions.
16 changes: 8 additions & 8 deletions eng/Version.Details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>45d845e04c05fbe5da9838c454bbc3af1df6be81</Sha>
</Dependency>
<Dependency Name="Microsoft.Testing.Extensions.CodeCoverage" Version="17.13.2-preview.24605.2">
<Dependency Name="Microsoft.Testing.Extensions.CodeCoverage" Version="17.13.2-preview.24606.2">
<Uri>https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage</Uri>
<Sha>eb105201ff904a7d5c6fac39de838a4bb6966a93</Sha>
</Dependency>
<Dependency Name="Microsoft.Testing.Extensions.Retry" Version="1.5.0-preview.24604.2">
<Dependency Name="Microsoft.Testing.Extensions.Retry" Version="1.5.0-preview.24608.1">
<Uri>https://github.com/microsoft/testanywhere</Uri>
<Sha>33cb71263430f0dbe8f9ffd4edd76d837cb05259</Sha>
</Dependency>
<Dependency Name="MSTest.Engine" Version="1.0.0-alpha.24473.2">
<Uri>https://github.com/microsoft/testanywhere</Uri>
<Sha>aa2fcc8616d988b234bc1d218465b20c56d0b82f</Sha>
<Sha>2346f405dcb5150b567970995dc978feb26b2db0</Sha>
</Dependency>
<!-- Intermediate is necessary for source build. -->
<Dependency Name="Microsoft.SourceBuild.Intermediate.diagnostics" Version="9.0.0-preview.24566.1">
Expand All @@ -43,11 +43,11 @@
<Sha>94798e07efab2663f2d1a71862780bc365d2e3ab</Sha>
<SourceBuild RepoName="source-build-reference-packages" ManagedOnly="true" />
</Dependency>
<!-- Intermediate is necessary for source build. -->
<Dependency Name="Microsoft.SourceBuild.Intermediate.arcade" Version="10.0.0-beta.24604.4">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>45d845e04c05fbe5da9838c454bbc3af1df6be81</Sha>
<SourceBuild RepoName="arcade" ManagedOnly="true" />
<!-- Intermediate is necessary for source build. -->
<Dependency Name="Microsoft.SourceBuild.Intermediate.arcade" Version="10.0.0-beta.24604.4">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>45d845e04c05fbe5da9838c454bbc3af1df6be81</Sha>
<SourceBuild RepoName="arcade" ManagedOnly="true" />
</Dependency>
</ToolsetDependencies>
</Dependencies>
4 changes: 2 additions & 2 deletions eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
</PropertyGroup>
<PropertyGroup Label="MSTest prod dependencies - darc updated">
<MicrosoftDotNetBuildTasksTemplatingPackageVersion>10.0.0-beta.24604.4</MicrosoftDotNetBuildTasksTemplatingPackageVersion>
<MicrosoftTestingExtensionsCodeCoverageVersion>17.13.2-preview.24605.2</MicrosoftTestingExtensionsCodeCoverageVersion>
<MicrosoftTestingExtensionsCodeCoverageVersion>17.13.2-preview.24606.2</MicrosoftTestingExtensionsCodeCoverageVersion>
<!-- comment to facilitate merge conflicts -->
<MicrosoftTestingExtensionsRetryVersion>1.5.0-preview.24604.2</MicrosoftTestingExtensionsRetryVersion>
<MicrosoftTestingExtensionsRetryVersion>1.5.0-preview.24608.1</MicrosoftTestingExtensionsRetryVersion>
<MSTestEngineVersion>1.0.0-alpha.24473.2</MSTestEngineVersion>
</PropertyGroup>
</Project>
28 changes: 14 additions & 14 deletions src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,16 @@ public AssemblyEnumerator(MSTestSettings settings) =>
internal ICollection<UnitTestElement> EnumerateAssembly(
string assemblyFileName,
[StringSyntax(StringSyntaxAttribute.Xml, nameof(runSettingsXml))] string? runSettingsXml,
out ICollection<string> warnings)
List<string> warnings)
{
DebugEx.Assert(!StringEx.IsNullOrWhiteSpace(assemblyFileName), "Invalid assembly file name.");
var warningMessages = new List<string>();
var tests = new List<UnitTestElement>();
// Contains list of assembly/class names for which we have already added fixture tests.
var fixturesTests = new HashSet<string>();

Assembly assembly = PlatformServiceProvider.Instance.FileOperations.LoadAssembly(assemblyFileName, isReflectionOnly: false);

Type[] types = GetTypes(assembly, assemblyFileName, warningMessages);
Type[] types = GetTypes(assembly, assemblyFileName, warnings);
bool discoverInternals = ReflectHelper.GetDiscoverInternalsAttribute(assembly) != null;
TestIdGenerationStrategy testIdGenerationStrategy = ReflectHelper.GetTestIdGenerationStrategy(assembly);

Expand Down Expand Up @@ -120,12 +119,11 @@ internal ICollection<UnitTestElement> EnumerateAssembly(
continue;
}

List<UnitTestElement> testsInType = DiscoverTestsInType(assemblyFileName, testRunParametersFromRunSettings, type, warningMessages, discoverInternals,
List<UnitTestElement> testsInType = DiscoverTestsInType(assemblyFileName, testRunParametersFromRunSettings, type, warnings, discoverInternals,
dataSourcesUnfoldingStrategy, testIdGenerationStrategy, fixturesTests);
tests.AddRange(testsInType);
}

warnings = warningMessages;
return tests;
}

Expand Down Expand Up @@ -238,8 +236,7 @@ private List<UnitTestElement> DiscoverTestsInType(
{
typeFullName = type.FullName;
TypeEnumerator testTypeEnumerator = GetTypeEnumerator(type, assemblyFileName, discoverInternals, testIdGenerationStrategy);
ICollection<UnitTestElement>? unitTestCases = testTypeEnumerator.Enumerate(out ICollection<string> warningsFromTypeEnumerator);
warningMessages.AddRange(warningsFromTypeEnumerator);
List<UnitTestElement>? unitTestCases = testTypeEnumerator.Enumerate(warningMessages);

if (unitTestCases != null)
{
Expand Down Expand Up @@ -369,11 +366,12 @@ private static bool TryUnfoldITestDataSources(UnitTestElement test, TestMethodIn
// there is at least one (we determine this in TypeEnumerator.GetTestFromMethod.
IEnumerable<ITestDataSource> testDataSources = ReflectHelper.Instance.GetDerivedAttributes<Attribute>(testMethodInfo.MethodInfo, inherit: false).OfType<ITestDataSource>();

// We need to use a temporary list to avoid adding tests to the main list if we fail to expand any data source.
List<UnitTestElement> tempListOfTests = new();

try
{
bool isDataDriven = false;
// We need to use a temporary list to avoid adding tests to the main list if we fail to expand any data source.
List<UnitTestElement> tempListOfTests = new();
foreach (ITestDataSource dataSource in testDataSources)
{
isDataDriven = true;
Expand All @@ -386,11 +384,6 @@ private static bool TryUnfoldITestDataSources(UnitTestElement test, TestMethodIn
}
}

if (isDataDriven && tempListOfTests.Count > 0)
{
tests.AddRange(tempListOfTests);
}

return isDataDriven;
}
catch (Exception ex)
Expand All @@ -399,6 +392,13 @@ private static bool TryUnfoldITestDataSources(UnitTestElement test, TestMethodIn
PlatformServiceProvider.Instance.AdapterTraceLogger.LogInfo($"DynamicDataEnumerator: {message}");
return false;
}
finally
{
if (tempListOfTests.Count > 0)
{
tests.AddRange(tempListOfTests);
}
}
}

private static bool TryUnfoldITestDataSource(ITestDataSource dataSource, TestDataSourceUnfoldingStrategy dataSourcesUnfoldingStrategy, UnitTestElement test, ReflectionTestMethodInfo methodInfo, List<UnitTestElement> tests)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ internal sealed class AssemblyEnumeratorWrapper
/// <param name="runSettings"> The run Settings. </param>
/// <param name="warnings"> Contains warnings if any, that need to be passed back to the caller. </param>
/// <returns> A collection of test elements. </returns>
internal ICollection<UnitTestElement>? GetTests(string? assemblyFileName, IRunSettings? runSettings, out ICollection<string> warnings)
internal ICollection<UnitTestElement>? GetTests(string? assemblyFileName, IRunSettings? runSettings, out List<string> warnings)
{
warnings = new List<string>();

Expand All @@ -52,7 +52,7 @@ internal sealed class AssemblyEnumeratorWrapper
}

// Load the assembly in isolation if required.
return GetTestsInIsolation(fullFilePath, runSettings, out warnings);
return GetTestsInIsolation(fullFilePath, runSettings, warnings);
}
catch (FileNotFoundException ex)
{
Expand Down Expand Up @@ -98,7 +98,7 @@ internal sealed class AssemblyEnumeratorWrapper
}
}

private static ICollection<UnitTestElement> GetTestsInIsolation(string fullFilePath, IRunSettings? runSettings, out ICollection<string> warnings)
private static ICollection<UnitTestElement> GetTestsInIsolation(string fullFilePath, IRunSettings? runSettings, List<string> warnings)
{
using MSTestAdapter.PlatformServices.Interface.ITestSourceHost isolationHost = PlatformServiceProvider.Instance.CreateTestSourceHost(fullFilePath, runSettings, frameworkHandle: null);

Expand All @@ -117,6 +117,6 @@ private static ICollection<UnitTestElement> GetTestsInIsolation(string fullFileP
PlatformServiceProvider.Instance.AdapterTraceLogger.LogWarning(Resource.OlderTFMVersionFound);
}

return assemblyEnumerator.EnumerateAssembly(fullFilePath, xml, out warnings);
return assemblyEnumerator.EnumerateAssembly(fullFilePath, xml, warnings);
}
}
20 changes: 8 additions & 12 deletions src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Reflection;
Expand Down Expand Up @@ -52,10 +51,8 @@ internal TypeEnumerator(Type type, string assemblyFilePath, ReflectHelper reflec
/// </summary>
/// <param name="warnings"> Contains warnings if any, that need to be passed back to the caller. </param>
/// <returns> list of test cases.</returns>
internal virtual ICollection<UnitTestElement>? Enumerate(out ICollection<string> warnings)
internal virtual List<UnitTestElement>? Enumerate(List<string> warnings)
{
warnings = new Collection<string>();

if (!_typeValidator.IsValidTestClass(_type, warnings))
{
return null;
Expand All @@ -70,11 +67,11 @@ internal TypeEnumerator(Type type, string assemblyFilePath, ReflectHelper reflec
/// </summary>
/// <param name="warnings"> Contains warnings if any, that need to be passed back to the caller. </param>
/// <returns> List of Valid Tests. </returns>
internal Collection<UnitTestElement> GetTests(ICollection<string> warnings)
internal List<UnitTestElement> GetTests(List<string> warnings)
{
bool foundDuplicateTests = false;
var foundTests = new HashSet<string>();
var tests = new Collection<UnitTestElement>();
var tests = new List<UnitTestElement>();

// Test class is already valid. Verify methods.
// PERF: GetRuntimeMethods is used here to get all methods, including non-public, and static methods.
Expand Down Expand Up @@ -117,12 +114,11 @@ internal Collection<UnitTestElement> GetTests(ICollection<string> warnings)
currentType = currentType.BaseType;
}

return new Collection<UnitTestElement>(
tests.GroupBy(
t => t.TestMethod.Name,
(_, elements) =>
elements.OrderBy(t => inheritanceDepths[t.TestMethod.DeclaringClassFullName ?? t.TestMethod.FullClassName]).First())
.ToList());
return tests.GroupBy(
t => t.TestMethod.Name,
(_, elements) =>
elements.OrderBy(t => inheritanceDepths[t.TestMethod.DeclaringClassFullName ?? t.TestMethod.FullClassName]).First())
.ToList();
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Adapter/MSTest.TestAdapter/Discovery/TypeValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ internal TypeValidator(ReflectHelper reflectHelper, bool discoverInternals)
/// <param name="type">The reflected type.</param>
/// <param name="warnings">Contains warnings if any, that need to be passed back to the caller.</param>
/// <returns>Return true if it is a valid test class.</returns>
internal virtual bool IsValidTestClass(Type type, ICollection<string> warnings)
internal virtual bool IsValidTestClass(Type type, List<string> warnings)
{
// PERF: We are doing caching reflection here, meaning we will cache every class info in the
// assembly, this is because when we discover and run we will repeatedly inspect all the types in the assembly, and this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ internal virtual void DiscoverTestsInSource(
ITestCaseDiscoverySink discoverySink,
IDiscoveryContext? discoveryContext)
{
ICollection<UnitTestElement>? testElements = _assemblyEnumeratorWrapper.GetTests(source, discoveryContext?.RunSettings, out ICollection<string>? warnings);
ICollection<UnitTestElement>? testElements = _assemblyEnumeratorWrapper.GetTests(source, discoveryContext?.RunSettings, out List<string> warnings);

bool treatDiscoveryWarningsAsErrors = MSTestSettings.CurrentSettings.TreatDiscoveryWarningsAsErrors;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,6 @@ public void RenderProgress(TestProgressState?[] progress)

// Use just ascii here, so we don't put too many restrictions on fonts needing to
// properly show unicode, or logs being saved in particular encoding.
TestDetailState? activeTest = p.TestNodeResultsState?.GetFirstRunningTask();
string? detail = !RoslynString.IsNullOrWhiteSpace(activeTest?.Text) ? $"- {activeTest.Text}" : null;
Append('[');
SetColor(TerminalColor.DarkGreen);
Append('+');
Expand Down Expand Up @@ -226,10 +224,12 @@ public void RenderProgress(TestProgressState?[] progress)
Append(')');
}

if (!RoslynString.IsNullOrWhiteSpace(detail))
TestDetailState? activeTest = p.TestNodeResultsState?.GetRunningTasks(1).FirstOrDefault();
if (!RoslynString.IsNullOrWhiteSpace(activeTest?.Text))
{
Append(" - ");
Append(detail);
Append(activeTest.Text);
Append(' ');
}

Append(durationString);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ public TestNodeResultsState(long id)

public void RemoveRunningTestNode(string uid) => _testNodeProgressStates.TryRemove(uid, out _);

public TestDetailState? GetFirstRunningTask() => _testNodeProgressStates.FirstOrDefault().Value;

public IEnumerable<TestDetailState> GetRunningTasks(int maxCount)
{
var sortedDetails = _testNodeProgressStates
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ public void CustomTestDataSourceTests()
VerifyE2E.ContainsTestsPassed(testResults, "CustomTestDataSourceTestMethod1 (1,2,3)", "CustomTestDataSourceTestMethod1 (4,5,6)");
}

public void CustomEmptyTestDataSourceTests()
{
// Arrange
string assemblyPath = GetAssetFullPath(TestAssetName);

// Act
ImmutableArray<TestCase> testCases = DiscoverTests(assemblyPath, "CustomEmptyTestDataSourceTestMethod");
ImmutableArray<TestResult> testResults = RunTests(testCases);

// Assert
VerifyE2E.ContainsTestsFailed(testResults, new string[] { null });
}

public void AssertExtensibilityTests()
{
// Arrange
Expand All @@ -41,7 +54,6 @@ public void AssertExtensibilityTests()
ImmutableArray<TestResult> testResults = RunTests(testCases);

// Assert
VerifyE2E.ContainsTestsPassed(testResults, "BasicAssertExtensionTest", "ChainedAssertExtensionTest");
VerifyE2E.ContainsTestsFailed(testResults, "BasicFailingAssertExtensionTest", "ChainedFailingAssertExtensionTest");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public void ExecuteTestDataSourceExtensibilityTests()
{
InvokeVsTestForExecution([TestAssetName]);
ValidatePassedTestsContain("CustomTestDataSourceTestMethod1 (1,2,3)", "CustomTestDataSourceTestMethod1 (4,5,6)");
ValidateFailedTestsContain(false, "FxExtensibilityTestProject.TestDataSourceExTests.CustomTestDataSourceTestMethod1");
ValidateFailedTestsContain(false, "FxExtensibilityTestProject.TestDataSourceExTests.CustomEmptyTestDataSourceTestMethod");
}

public void ExecuteDynamicDataExtensibilityTests()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ public class TestDataSourceExTests
{
[TestMethod]
[CustomTestDataSource]
[CustomEmptyTestDataSource]
public void CustomTestDataSourceTestMethod1(int a, int b, int c)
{
Assert.AreEqual(1, a % 3);
Expand All @@ -26,6 +25,15 @@ public void CustomTestDataSourceTestMethod1(int a, int b, int c)
public void CustomDisableExpansionTestDataSourceTestMethod1(int a, int b, int c)
{
}

[TestMethod]
[CustomEmptyTestDataSource]
public void CustomEmptyTestDataSourceTestMethod(int a, int b, int c)
{
Assert.AreEqual(1, a % 3);
Assert.AreEqual(2, b % 3);
Assert.AreEqual(0, c % 3);
}
}

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
Expand Down
Loading

0 comments on commit 234c68f

Please sign in to comment.