From cbec84214cf17126989db1379af3984492e054c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Sat, 30 Dec 2023 11:19:08 +0100 Subject: [PATCH] MSTEST0006: Avoid '[ExpectedException]' --- .../AnalyzerReleases.Unshipped.md | 1 + ...AvoidExpectedExceptionAttributeAnalyzer.cs | 57 +++++++++++++++++++ .../MSTest.Analyzers/Helpers/DiagnosticIds.cs | 1 + .../Helpers/WellKnownTypeNames.cs | 1 + .../MSTest.Analyzers/Resources.Designer.cs | 27 +++++++++ src/Analyzers/MSTest.Analyzers/Resources.resx | 9 +++ .../MSTest.Analyzers/xlf/Resources.cs.xlf | 15 +++++ .../MSTest.Analyzers/xlf/Resources.de.xlf | 15 +++++ .../MSTest.Analyzers/xlf/Resources.es.xlf | 15 +++++ .../MSTest.Analyzers/xlf/Resources.fr.xlf | 15 +++++ .../MSTest.Analyzers/xlf/Resources.it.xlf | 15 +++++ .../MSTest.Analyzers/xlf/Resources.ja.xlf | 15 +++++ .../MSTest.Analyzers/xlf/Resources.ko.xlf | 15 +++++ .../MSTest.Analyzers/xlf/Resources.pl.xlf | 15 +++++ .../MSTest.Analyzers/xlf/Resources.pt-BR.xlf | 15 +++++ .../MSTest.Analyzers/xlf/Resources.ru.xlf | 15 +++++ .../MSTest.Analyzers/xlf/Resources.tr.xlf | 15 +++++ .../xlf/Resources.zh-Hans.xlf | 15 +++++ .../xlf/Resources.zh-Hant.xlf | 15 +++++ ...ExpectedExceptionAttributeAnalyzerTests.cs | 51 +++++++++++++++++ .../testsbaseline.txt | 3 +- 21 files changed, 344 insertions(+), 1 deletion(-) create mode 100644 src/Analyzers/MSTest.Analyzers/AvoidExpectedExceptionAttributeAnalyzer.cs create mode 100644 test/UnitTests/MSTest.Analyzers.UnitTests/AvoidExpectedExceptionAttributeAnalyzerTests.cs diff --git a/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md b/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md index 4f9377bc8a..8142a3e5d1 100644 --- a/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md +++ b/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md @@ -10,3 +10,4 @@ MSTEST0002 | Usage | Warning | TestClassShouldBeValidAnalyzer, [Documentation](h MSTEST0003 | Usage | Warning | TestMethodShouldBeValidAnalyzer, [Documentation](https://github.com/microsoft/testfx/blob/main/docs/analyzers/MSTEST0003.md) MSTEST0004 | Design | Disabled | PublicTypeShouldBeTestClassAnalyzer, [Documentation](https://github.com/microsoft/testfx/blob/main/docs/analyzers/MSTEST0004.md) MSTEST0005 | Usage | Warning | TestContextShouldBeValidAnalyzer, [Documentation](https://github.com/microsoft/testfx/blob/main/docs/analyzers/MSTEST0005.md) +MSTEST0006 | Design | Info | AvoidExpectedExceptionAttributeAnalyzer, [Documentation](https://github.com/microsoft/testfx/blob/main/docs/analyzers/MSTEST0002.md) diff --git a/src/Analyzers/MSTest.Analyzers/AvoidExpectedExceptionAttributeAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/AvoidExpectedExceptionAttributeAnalyzer.cs new file mode 100644 index 0000000000..c694477adf --- /dev/null +++ b/src/Analyzers/MSTest.Analyzers/AvoidExpectedExceptionAttributeAnalyzer.cs @@ -0,0 +1,57 @@ +// 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.Immutable; + +using Analyzer.Utilities.Extensions; + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; + +using MSTest.Analyzers.Helpers; + +namespace MSTest.Analyzers; + +[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] +public sealed class AvoidExpectedExceptionAttributeAnalyzer : DiagnosticAnalyzer +{ + private static readonly LocalizableResourceString Title = new(nameof(Resources.AvoidExpectedExceptionAttributeTitle), Resources.ResourceManager, typeof(Resources)); + private static readonly LocalizableResourceString Description = new(nameof(Resources.AvoidExpectedExceptionAttributeDescription), Resources.ResourceManager, typeof(Resources)); + private static readonly LocalizableResourceString MessageFormat = new(nameof(Resources.AvoidExpectedExceptionAttributeMessageFormat), Resources.ResourceManager, typeof(Resources)); + + internal static readonly DiagnosticDescriptor Rule = new( + DiagnosticIds.AvoidExpectedExceptionAttributeRuleId, + Title, + MessageFormat, + Categories.Design, + DiagnosticSeverity.Info, + isEnabledByDefault: true, + Description, + $"https://github.com/microsoft/testfx/blob/main/docs/analyzers/{DiagnosticIds.AvoidExpectedExceptionAttributeRuleId}.md"); + + public override ImmutableArray SupportedDiagnostics { get; } + = ImmutableArray.Create(Rule); + + public override void Initialize(AnalysisContext context) + { + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); + context.EnableConcurrentExecution(); + + context.RegisterCompilationStartAction(context => + { + if (context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingExpectedExceptionAttribute, out var expectedExceptionAttributeSymbol)) + { + context.RegisterSymbolAction(context => AnalyzeSymbol(context, expectedExceptionAttributeSymbol), SymbolKind.Method); + } + }); + } + + private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbol expectedExceptionAttributeSymbol) + { + var methodSymbol = (IMethodSymbol)context.Symbol; + if (methodSymbol.GetAttributes().Any(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, expectedExceptionAttributeSymbol))) + { + context.ReportDiagnostic(methodSymbol.CreateDiagnostic(Rule)); + } + } +} diff --git a/src/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs b/src/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs index 982f008a90..66a93c0709 100644 --- a/src/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs +++ b/src/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs @@ -10,4 +10,5 @@ internal static class DiagnosticIds public const string TestMethodShouldBeValidRuleId = "MSTEST0003"; public const string PublicTypeShouldBeTestClassRuleId = "MSTEST0004"; public const string TestContextShouldBeValidRuleId = "MSTEST0005"; + public const string AvoidExpectedExceptionAttributeRuleId = "MSTEST0006"; } diff --git a/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs b/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs index b9d1733eca..fd73b435b5 100644 --- a/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs +++ b/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs @@ -12,6 +12,7 @@ internal static class WellKnownTypeNames public const string MicrosoftVisualStudioTestToolsUnitTestingTestClassAttribute = "Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute"; public const string MicrosoftVisualStudioTestToolsUnitTestingTestContext = "Microsoft.VisualStudio.TestTools.UnitTesting.TestContext"; public const string MicrosoftVisualStudioTestToolsUnitTestingTestMethodAttribute = "Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute"; + public const string MicrosoftVisualStudioTestToolsUnitTestingExpectedExceptionAttribute = "Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedExceptionAttribute"; public const string SystemThreadingTasksTask = "System.Threading.Tasks.Task"; public const string SystemThreadingTasksTask1 = "System.Threading.Tasks.Task`1"; diff --git a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs index d55185bdb2..d6e2f794da 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs +++ b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs @@ -60,6 +60,33 @@ internal Resources() { } } + /// + /// Looks up a localized string similar to Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption.. + /// + internal static string AvoidExpectedExceptionAttributeDescription { + get { + return ResourceManager.GetString("AvoidExpectedExceptionAttributeDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]'. + /// + internal static string AvoidExpectedExceptionAttributeMessageFormat { + get { + return ResourceManager.GetString("AvoidExpectedExceptionAttributeMessageFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Avoid '[ExpectedException]'. + /// + internal static string AvoidExpectedExceptionAttributeTitle { + get { + return ResourceManager.GetString("AvoidExpectedExceptionAttributeTitle", resourceCulture); + } + } + /// /// Looks up a localized string similar to It's considered a good practice to have only test classes marked public in a test project.. /// diff --git a/src/Analyzers/MSTest.Analyzers/Resources.resx b/src/Analyzers/MSTest.Analyzers/Resources.resx index a8c61b0734..03b7a074ed 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.resx +++ b/src/Analyzers/MSTest.Analyzers/Resources.resx @@ -117,6 +117,15 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + + + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + + + Avoid '[ExpectedException]' + It's considered a good practice to have only test classes marked public in a test project. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index 5c336dccad..6edef661a7 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -2,6 +2,21 @@ + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + + + + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + + + + Avoid '[ExpectedException]' + Avoid '[ExpectedException]' + + It's considered a good practice to have only test classes marked public in a test project. Osvědčeným postupem je označit jako veřejné v testovacím projektu jen testovací třídy. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf index 4241d3a448..93aab3b338 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf @@ -2,6 +2,21 @@ + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + + + + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + + + + Avoid '[ExpectedException]' + Avoid '[ExpectedException]' + + It's considered a good practice to have only test classes marked public in a test project. Es wird als bewährte Methode angesehen, nur Testklassen in einem Testprojekt als öffentlich gekennzeichnet zu lassen. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf index f7f1357a33..dd242c5373 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf @@ -2,6 +2,21 @@ + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + + + + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + + + + Avoid '[ExpectedException]' + Avoid '[ExpectedException]' + + It's considered a good practice to have only test classes marked public in a test project. Se considera una buena práctica tener solo clases de prueba marcadas como públicas en un proyecto de prueba. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index 64d324f596..875eb7a360 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -2,6 +2,21 @@ + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + + + + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + + + + Avoid '[ExpectedException]' + Avoid '[ExpectedException]' + + It's considered a good practice to have only test classes marked public in a test project. C’est considéré comme une bonne pratique d’avoir uniquement des classes de test marquées comme publiques dans un projet de test. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf index fd7a1f6814..f53c793a67 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf @@ -2,6 +2,21 @@ + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + + + + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + + + + Avoid '[ExpectedException]' + Avoid '[ExpectedException]' + + It's considered a good practice to have only test classes marked public in a test project. È consigliabile che solo le classi di test siano contrassegnate come pubbliche in un progetto di test. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index 41f3778353..f2a908ec8b 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -2,6 +2,21 @@ + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + + + + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + + + + Avoid '[ExpectedException]' + Avoid '[ExpectedException]' + + It's considered a good practice to have only test classes marked public in a test project. テスト プロジェクトでは、テスト クラスのみをパブリックとしてマークすることをお勧めします。 diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index 4524ed7eef..58d1648cfd 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -2,6 +2,21 @@ + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + + + + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + + + + Avoid '[ExpectedException]' + Avoid '[ExpectedException]' + + It's considered a good practice to have only test classes marked public in a test project. 테스트 프로젝트에서 공용으로 표시된 테스트 클래스만 사용하는 것이 좋습니다. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index 4b329e5899..1ba6587687 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -2,6 +2,21 @@ + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + + + + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + + + + Avoid '[ExpectedException]' + Avoid '[ExpectedException]' + + It's considered a good practice to have only test classes marked public in a test project. Uważa się, że dobrą praktyką jest oznaczanie tylko klas testowych jako publicznych w projekcie testowym. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index a3623194da..9b5eb7f333 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -2,6 +2,21 @@ + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + + + + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + + + + Avoid '[ExpectedException]' + Avoid '[ExpectedException]' + + It's considered a good practice to have only test classes marked public in a test project. É considerado uma boa prática ter somente classes de teste marcadas como públicas em um projeto de teste. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index b299fc71c4..30e1ab3166 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -2,6 +2,21 @@ + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + + + + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + + + + Avoid '[ExpectedException]' + Avoid '[ExpectedException]' + + It's considered a good practice to have only test classes marked public in a test project. Рекомендуется использовать только тестовые классы, помеченные как общедоступные в тестовом проекте. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index 34f7aa738e..7f976b40d8 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -2,6 +2,21 @@ + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + + + + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + + + + Avoid '[ExpectedException]' + Avoid '[ExpectedException]' + + It's considered a good practice to have only test classes marked public in a test project. Test projesinde yalnızca public olarak işaretlenmiş test sınıflarının olması iyi bir uygulama olarak kabul edilir. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index 46ba2cddae..901f38419c 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -2,6 +2,21 @@ + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + + + + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + + + + Avoid '[ExpectedException]' + Avoid '[ExpectedException]' + + It's considered a good practice to have only test classes marked public in a test project. 在测试项目中仅将测试类标记为“公开”是一种不错的做法。 diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf index 11ac87e2e5..523a346c56 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf @@ -2,6 +2,21 @@ + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. + + + + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + + + + Avoid '[ExpectedException]' + Avoid '[ExpectedException]' + + It's considered a good practice to have only test classes marked public in a test project. 在測試專案中僅將測試類別標記為公開被認為是一種很好的做法。 diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidExpectedExceptionAttributeAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidExpectedExceptionAttributeAnalyzerTests.cs new file mode 100644 index 0000000000..de84ef2a22 --- /dev/null +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidExpectedExceptionAttributeAnalyzerTests.cs @@ -0,0 +1,51 @@ +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.Testing.Framework; +using Microsoft.Testing.TestInfrastructure; + +using VerifyCS = MSTest.Analyzers.Test.CSharpCodeFixVerifier< + MSTest.Analyzers.AvoidExpectedExceptionAttributeAnalyzer, + Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; + +namespace MSTest.Analyzers.Test; + +[TestGroup] +public sealed class AvoidExpectedExceptionAttributeAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +{ + public async Task WhenUsed_Diagnostic() + { + var code = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TestClass + { + [ExpectedException(typeof(System.Exception))] + [TestMethod] + public void [|TestMethod|]() + { + } + + [ExpectedException(typeof(System.Exception), "Some message")] + [TestMethod] + public void [|TestMethod2|]() + { + } + + [ExpectedException(typeof(System.Exception), AllowDerivedTypes = true)] + [TestMethod] + public void [|TestMethod3|]() + { + } + + [ExpectedException(typeof(System.Exception), "Some message", AllowDerivedTypes = true)] + [TestMethod] + public void [|TestMethod4|]() + { + } + } + """; + + await VerifyCS.VerifyAnalyzerAsync(code); + } +} diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/testsbaseline.txt b/test/UnitTests/MSTest.Analyzers.UnitTests/testsbaseline.txt index f186f97395..29577241d7 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/testsbaseline.txt +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/testsbaseline.txt @@ -1,4 +1,5 @@ -MSTest.Analyzers.UnitTests.MSTest.Analyzers.Test.PublicClassShouldBeTestClassAnalyzerTests.WhenTypeIsNotPublicAndNotTestClass_NoDiagnostic() +MSTest.Analyzers.UnitTests.MSTest.Analyzers.Test.AvoidExpectedExceptionAttributeAnalyzerTests.WhenUsed_Diagnostic() +MSTest.Analyzers.UnitTests.MSTest.Analyzers.Test.PublicClassShouldBeTestClassAnalyzerTests.WhenTypeIsNotPublicAndNotTestClass_NoDiagnostic() MSTest.Analyzers.UnitTests.MSTest.Analyzers.Test.PublicClassShouldBeTestClassAnalyzerTests.WhenTypeIsPublicAndNotTestClass_Diagnostic() MSTest.Analyzers.UnitTests.MSTest.Analyzers.Test.TestClassShouldBeValidAnalyzerTests.WhenClassIsGeneric_Diagnostic() MSTest.Analyzers.UnitTests.MSTest.Analyzers.Test.TestClassShouldBeValidAnalyzerTests.WhenClassIsInnerAndNotPublicTestClass_Diagnostic(string) (accessibility: "internal")