diff --git a/src/Analyzers/MSTest.Analyzers/UseDeploymentItemWithTestMethodOrTestClassAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/UseDeploymentItemWithTestMethodOrTestClassAnalyzer.cs index 6df26db2a1..09e939690e 100644 --- a/src/Analyzers/MSTest.Analyzers/UseDeploymentItemWithTestMethodOrTestClassAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/UseDeploymentItemWithTestMethodOrTestClassAnalyzer.cs @@ -52,6 +52,15 @@ public override void Initialize(AnalysisContext context) private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbol testMethodAttributeSymbol, INamedTypeSymbol testClassAttributeSymbol, INamedTypeSymbol deploymentItemAttributeSymbol) { + if (context.Symbol is INamedTypeSymbol { IsAbstract: true }) + { + // As [DeploymentItem] attribute is inherited, it's okay to be present on an abstract class that is not a test class. + // See https://github.com/microsoft/testfx/issues/2683 for information. + // For now, we do the IsAbstract check specifically for classes and not methods. + // If we got a convincing feedback around a false positive for the attribute on an abstract method, we can adjust the check. + return; + } + bool hasDeploymentItemAttribute = false; bool isTestMethodOrTestClass = false; foreach (AttributeData attribute in context.Symbol.GetAttributes()) diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/UseDeploymentItemWithTestMethodOrTestClassAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/UseDeploymentItemWithTestMethodOrTestClassAnalyzerTests.cs index 228f7c2f41..4b3648394f 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/UseDeploymentItemWithTestMethodOrTestClassAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseDeploymentItemWithTestMethodOrTestClassAnalyzerTests.cs @@ -84,6 +84,20 @@ public void MyTestMethod() await VerifyCS.VerifyAnalyzerAsync(code); } + public async Task WhenAnAbstractClassHasDeploymentItem_NoDiagnostic() + { + string code = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [DeploymentItem("")] + public abstract class MyTestClass + { + } + """; + + await VerifyCS.VerifyAnalyzerAsync(code); + } + public async Task WhenAClassHasDeploymentItem_Diagnostic() { string code = """