diff --git a/src/Analyzers/MSTest.Analyzers/UseParallelizeAttributeAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/UseParallelizeAttributeAnalyzer.cs index b3295b921e..f9bccc3686 100644 --- a/src/Analyzers/MSTest.Analyzers/UseParallelizeAttributeAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/UseParallelizeAttributeAnalyzer.cs @@ -44,6 +44,13 @@ public override void Initialize(AnalysisContext context) private static void AnalyzeCompilation(CompilationAnalysisContext context) { + bool hasTestAdapter = context.Compilation.ReferencedAssemblyNames.Any(asm => asm.Name == "Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"); + if (!hasTestAdapter) + { + // We shouldn't produce a diagnostic if only the test framework is referenced, but not the adapter. + return; + } + INamedTypeSymbol? parallelizeAttributeSymbol = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingParallelizeAttribute); INamedTypeSymbol? doNotParallelizeAttributeSymbol = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingDoNotParallelizeAttribute); diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/UseParallelizeAttributeAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/UseParallelizeAttributeAnalyzerTests.cs index 7dcf190ed1..8872cb744b 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/UseParallelizeAttributeAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseParallelizeAttributeAnalyzerTests.cs @@ -1,6 +1,10 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; +using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; + using VerifyCS = MSTest.Analyzers.Test.CSharpCodeFixVerifier< MSTest.Analyzers.UseParallelizeAttributeAnalyzer, Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; @@ -10,10 +14,30 @@ namespace MSTest.Analyzers.Test; [TestClass] public class UseParallelizeAttributeAnalyzerTests { + private static async Task VerifyAsync(string code, bool includeTestAdapter, params DiagnosticResult[] expected) + { + var test = new VerifyCS.Test + { + TestCode = code, + }; + + if (includeTestAdapter) + { + // NOTE: Test constructor already adds TestFramework refs. + test.TestState.AdditionalReferences.Add(MetadataReference.CreateFromFile(typeof(MSTestExecutor).Assembly.Location)); + } + + test.ExpectedDiagnostics.AddRange(expected); + await test.RunAsync(); + } + + [TestMethod] + public async Task WhenNoAttributeSpecified_TestAdapterNotReferenced_NoDiagnostic() + => await VerifyAsync(string.Empty, includeTestAdapter: false); + [TestMethod] - public async Task WhenNoAttributeSpecified_Diagnostic() => await VerifyCS.VerifyAnalyzerAsync( - string.Empty, - VerifyCS.Diagnostic(UseParallelizeAttributeAnalyzer.Rule).WithNoLocation()); + public async Task WhenNoAttributeSpecified_TestAdapterReferenced_Diagnostic() + => await VerifyAsync(string.Empty, includeTestAdapter: true, VerifyCS.Diagnostic(UseParallelizeAttributeAnalyzer.Rule).WithNoLocation()); [TestMethod] public async Task WhenParallelizeAttributeSet_NoDiagnostic() @@ -24,7 +48,8 @@ public async Task WhenParallelizeAttributeSet_NoDiagnostic() [assembly: Parallelize(Workers = 2, Scope = ExecutionScope.MethodLevel)] """; - await VerifyCS.VerifyAnalyzerAsync(code); + await VerifyAsync(code, includeTestAdapter: true); + await VerifyAsync(code, includeTestAdapter: false); } [TestMethod] @@ -36,6 +61,7 @@ public async Task WhenDoNotParallelizeAttributeSet_NoDiagnostic() [assembly: DoNotParallelize] """; - await VerifyCS.VerifyAnalyzerAsync(code); + await VerifyAsync(code, includeTestAdapter: true); + await VerifyAsync(code, includeTestAdapter: false); } }