Skip to content

Commit 47b7a43

Browse files
authored
MSTEST0020: Prefer ctors over TestInitialize methods (#2582)
1 parent c083f91 commit 47b7a43

20 files changed

+308
-0
lines changed

src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
Rule ID | Category | Severity | Notes
66
--------|----------|----------|-------
77
MSTEST0017 | Usage | Info | AssertionArgsShouldBePassedInCorrectOrder, [Documentation](https://learn.microsoft.com/dotnet/core/testing/mstest-analyzers/mstest0017)
8+
MSTEST0020 | Design | Disabled | PreferConstructorOverTestInitializeAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/core/testing/mstest-analyzers/mstest0020)

src/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ internal static class DiagnosticIds
2222
public const string TestMethodShouldNotBeIgnoredRuleId = "MSTEST0015";
2323
public const string TestClassShouldHaveTestMethodRuleId = "MSTEST0016";
2424
public const string AssertionArgsShouldBePassedInCorrectOrderRuleId = "MSTEST0017";
25+
public const string PreferConstructorOverTestInitializeRuleId = "MSTEST0020";
2526
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System.Collections.Immutable;
5+
6+
using Analyzer.Utilities.Extensions;
7+
8+
using Microsoft.CodeAnalysis;
9+
using Microsoft.CodeAnalysis.Diagnostics;
10+
11+
using MSTest.Analyzers.Helpers;
12+
13+
namespace MSTest.Analyzers;
14+
15+
[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
16+
public sealed class PreferConstructorOverTestInitializeAnalyzer : DiagnosticAnalyzer
17+
{
18+
private static readonly LocalizableResourceString Title = new(nameof(Resources.PreferConstructorOverTestInitializeTitle), Resources.ResourceManager, typeof(Resources));
19+
private static readonly LocalizableResourceString MessageFormat = new(nameof(Resources.PreferConstructorOverTestInitializeMessageFormat), Resources.ResourceManager, typeof(Resources));
20+
21+
internal static readonly DiagnosticDescriptor Rule = DiagnosticDescriptorHelper.Create(
22+
DiagnosticIds.PreferConstructorOverTestInitializeRuleId,
23+
Title,
24+
MessageFormat,
25+
null,
26+
Category.Design,
27+
DiagnosticSeverity.Info,
28+
isEnabledByDefault: false);
29+
30+
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; }
31+
= ImmutableArray.Create(Rule);
32+
33+
public override void Initialize(AnalysisContext context)
34+
{
35+
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
36+
context.EnableConcurrentExecution();
37+
38+
context.RegisterCompilationStartAction(context =>
39+
{
40+
if (context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingTestInitializeAttribute, out var testInitAttributeSymbol))
41+
{
42+
context.RegisterSymbolAction(context => AnalyzeSymbol(context, testInitAttributeSymbol), SymbolKind.Method);
43+
}
44+
});
45+
}
46+
47+
private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbol testInitAttributeSymbol)
48+
{
49+
IMethodSymbol methodSymbol = (IMethodSymbol)context.Symbol;
50+
51+
if (methodSymbol.IsTestInitializeMethod(testInitAttributeSymbol) && methodSymbol.ReturnsVoid)
52+
{
53+
context.ReportDiagnostic(methodSymbol.CreateDiagnostic(Rule));
54+
}
55+
}
56+
}

src/Analyzers/MSTest.Analyzers/Resources.Designer.cs

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Analyzers/MSTest.Analyzers/Resources.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,12 @@
301301
<data name="DataRowShouldBeValidTitle" xml:space="preserve">
302302
<value>DataRow should be valid</value>
303303
</data>
304+
<data name="PreferConstructorOverTestInitializeMessageFormat" xml:space="preserve">
305+
<value>Prefer constructors over TestInitialize methods</value>
306+
</data>
307+
<data name="PreferConstructorOverTestInitializeTitle" xml:space="preserve">
308+
<value>Prefer constructors over TestInitialize methods</value>
309+
</data>
304310
<data name="PublicTypeShouldBeTestClassDescription" xml:space="preserve">
305311
<value>It's considered a good practice to have only test classes marked public in a test project.</value>
306312
</data>

src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,16 @@
323323
<target state="translated">Argument DataRow by měl být platný</target>
324324
<note />
325325
</trans-unit>
326+
<trans-unit id="PreferConstructorOverTestInitializeMessageFormat">
327+
<source>Prefer constructors over TestInitialize methods</source>
328+
<target state="new">Prefer constructors over TestInitialize methods</target>
329+
<note />
330+
</trans-unit>
331+
<trans-unit id="PreferConstructorOverTestInitializeTitle">
332+
<source>Prefer constructors over TestInitialize methods</source>
333+
<target state="new">Prefer constructors over TestInitialize methods</target>
334+
<note />
335+
</trans-unit>
326336
<trans-unit id="PublicTypeShouldBeTestClassDescription">
327337
<source>It's considered a good practice to have only test classes marked public in a test project.</source>
328338
<target state="translated">Osvědčeným postupem je označit jako veřejné v testovacím projektu jen testovací třídy.</target>

src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,16 @@
319319
<target state="translated">DataRow muss gültig sein.</target>
320320
<note />
321321
</trans-unit>
322+
<trans-unit id="PreferConstructorOverTestInitializeMessageFormat">
323+
<source>Prefer constructors over TestInitialize methods</source>
324+
<target state="new">Prefer constructors over TestInitialize methods</target>
325+
<note />
326+
</trans-unit>
327+
<trans-unit id="PreferConstructorOverTestInitializeTitle">
328+
<source>Prefer constructors over TestInitialize methods</source>
329+
<target state="new">Prefer constructors over TestInitialize methods</target>
330+
<note />
331+
</trans-unit>
322332
<trans-unit id="PublicTypeShouldBeTestClassDescription">
323333
<source>It's considered a good practice to have only test classes marked public in a test project.</source>
324334
<target state="translated">Es wird als bewährte Methode angesehen, nur Testklassen in einem Testprojekt als öffentlich gekennzeichnet zu lassen.</target>

src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,16 @@
319319
<target state="translated">DataRow debe ser válido</target>
320320
<note />
321321
</trans-unit>
322+
<trans-unit id="PreferConstructorOverTestInitializeMessageFormat">
323+
<source>Prefer constructors over TestInitialize methods</source>
324+
<target state="new">Prefer constructors over TestInitialize methods</target>
325+
<note />
326+
</trans-unit>
327+
<trans-unit id="PreferConstructorOverTestInitializeTitle">
328+
<source>Prefer constructors over TestInitialize methods</source>
329+
<target state="new">Prefer constructors over TestInitialize methods</target>
330+
<note />
331+
</trans-unit>
322332
<trans-unit id="PublicTypeShouldBeTestClassDescription">
323333
<source>It's considered a good practice to have only test classes marked public in a test project.</source>
324334
<target state="translated">Se considera una buena práctica tener solo clases de prueba marcadas como públicas en un proyecto de prueba.</target>

src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,16 @@
319319
<target state="translated">DataRow doit être valide</target>
320320
<note />
321321
</trans-unit>
322+
<trans-unit id="PreferConstructorOverTestInitializeMessageFormat">
323+
<source>Prefer constructors over TestInitialize methods</source>
324+
<target state="new">Prefer constructors over TestInitialize methods</target>
325+
<note />
326+
</trans-unit>
327+
<trans-unit id="PreferConstructorOverTestInitializeTitle">
328+
<source>Prefer constructors over TestInitialize methods</source>
329+
<target state="new">Prefer constructors over TestInitialize methods</target>
330+
<note />
331+
</trans-unit>
322332
<trans-unit id="PublicTypeShouldBeTestClassDescription">
323333
<source>It's considered a good practice to have only test classes marked public in a test project.</source>
324334
<target state="translated">C’est considéré comme une bonne pratique d’avoir uniquement des classes de test marquées comme publiques dans un projet de test.</target>

src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,16 @@
319319
<target state="translated">DataRow deve essere valido</target>
320320
<note />
321321
</trans-unit>
322+
<trans-unit id="PreferConstructorOverTestInitializeMessageFormat">
323+
<source>Prefer constructors over TestInitialize methods</source>
324+
<target state="new">Prefer constructors over TestInitialize methods</target>
325+
<note />
326+
</trans-unit>
327+
<trans-unit id="PreferConstructorOverTestInitializeTitle">
328+
<source>Prefer constructors over TestInitialize methods</source>
329+
<target state="new">Prefer constructors over TestInitialize methods</target>
330+
<note />
331+
</trans-unit>
322332
<trans-unit id="PublicTypeShouldBeTestClassDescription">
323333
<source>It's considered a good practice to have only test classes marked public in a test project.</source>
324334
<target state="translated">È consigliabile che solo le classi di test siano contrassegnate come pubbliche in un progetto di test.</target>

0 commit comments

Comments
 (0)